Overview
Today’s notes will discuss a few Java topics which include Comparables and Exceptions. Exceptions and exception handling are not unique to Java; however, there are a few edge cases which we will discuss and list out clearly. On the other hand, Comparables are an integral part of the Java Object Oriented Programming approach. We will work with comparables many times throughout the course.
Comparables
Comparing numbers in Java is simple and all we have to do is use the built in comparison operators like \(>, <, ==, ...\) What do we do if we want to compare players in the NBA? Well, there is more to them than just numbers so we cannot do the following:
NBAPlayer MJ = new NBAPlayer("Michael Jordan", Mstats);
NBAPlayer LaVar = new NBAPlayer("LaVar Ball", Lstats);
System.out.println(LaVar > MJ); // Does this work?
This does not work and the error in specific is "bad operand types for binary operator". We cannot compare the two players. The fix is to have the NBAPlayer
class implement the Comparable
interface. This interface requires that a class implementing it also provide an implementation for the following method:
int compareTo(T o); // Don't worry about the T yet. If you want to get ahead, then read up on Java Generics!
The compareTo(T o)
method compares the object with the object given as argument to the method for an order. It returns a negative integer, zero, or positive integer if the object is less than, equal to, or greater than the input. By doing so, we can provide an ordering for any class! Why is this useful? We can use this to sort object and not just integers, and we can use this to show that LaVar Ball is better than Michael Jordan!
import java.util.*;
public class NBAPlayer implements Comparable<NBAPlayer> {
String name;
Map<String, Integer> stats;
NBAPlayer(String name, Map stats) {
this.name = name;
this.stats = stats;
}
@Override
public int compareTo(NBAPlayer o) {
if (name.equals("LaVar Ball")) {
return Integer.MAX_VALUE;
}
return stats.get("Championships").compareTo(o.stats.get("Championships"));
}
public static void main(String[] args) {
NBAPlayer MJ = new NBAPlayer("Michael Jordan", Mstats);
NBAPlayer LaVar = new NBAPlayer("LaVar Ball", Lstats);
if (LaVar.compareTo(MJ) > 0) {
System.out.println("Big Baller Brand");
} else {
System.out.println("The GOAT");
}
}
}
What does this print? If you guessed "Big Baller Brand", then you are correct! We will build on Comparable
and ordering later on in the course.
Exceptions
You may have noticed that sometimes your program will crash during runtime and output a message like "ArrayIndexOutOfBoundsException" or "NullPointerException". These are built in Java exceptions that the runtime machine will throw
when things go wrong. In the case that a program tries to write outside the bounds of an array, an "ArrayIndexOutOfBoundsException" will be thrown to prevent the user from doing malicious things! How smart of Java. This may be annoying and frustrating at times, but trust in that this is a life saving exception. If you are interested about why writing outside the bounds of an array is bad, read up on "Buffer Overflow" attacks. Now Java may be doing us a favor with throwing exceptions, but it just crashes our program! What if we don’t want that?
Exception Handling
A program crashing is often not a good thing. Say we have a program running on a new NASA project. We are testing a new rover and we have a Java program running the system. Assume the programmers working on the project never took 61B and do not know how to test their programs or handle exceptions. Oh no! During the rovers launch into space, there was a "NullPointerException" thrown. The program crashed and so did the rover. Tragic.
How can this be prevented? An exception is thrown
, but what can we do? Let’s try catching
it! We can use try-catch
to execute some code we fear may throw an exception. If the exception we specify in our catch block is thrown, then we can catch it and handle it.
Here are a couple rules to exception handling:
An exception not caught by its parent function will propegate up the stack. If never caught, then the program crashes.
The
finally
block is always executed before exiting thetry-catch
block. This is true even when atry-catch
block cannot catch the exception thrown.Java requires that all catch blocks are reachable. In effect, the following is not possible because the catch block for the
Kanye
exception is not reachable:Java only allows for one catch per
try-catch
block.
For some practice, check out these slides.