Learn Programming in Java


<<Previous | ToC | Next >>

Java Exceptions

Today you get to program exceptions properly. Start by reading about exceptions in my "Need to Know" page (unless you already did).

Java has a special class called "Exception" and all exceptions are subclasses of this base class. You don't need to know anything about subclasses today, but if you are curious, there is a brief introduction in my "Need to Know" page. When we start in on the GameEngine, you will need to know some of that. But not today. The point is, there are a zillion different kinds of exceptions built into Java (and you can define your own), but they are all variations on class "Exception". We will make use of that fact.

Most well-designed classes have a toString() method, and if you give an object variable (which is an instance of some class) to System.out.println, the toString method is called to generate a text description of this object, whatever the class designer thought you should know, so it can be printed. Often that's all a program does with exceptions, print out its text descriptor. You will start that way too.

I'm not going to tell you very much about exceptions, I'm going to point you at how to find out on the internet. Google Knows All. Not now, when we get there. It's easier to understand when you see it happening.

In the previous page we built a simple 4-function calculator something like this (some of your code omitted), except I made mine all integer:

public static void main() {
  int inval = 0, res = 0;
  char optor;
  while (true) {
    /// a. display the current result (initially =0)
    /// b. accept a command letter:
    /// c. if 'q' quit
    /// d. if 'c' clear
    /// e. accept a value
    inval = Zystem.ReadInt();
    /// f. if command is '+' add
    if (optor == '+') res = res+inval;
    /// g. else if '-' subtract
    /// h. else if '*' multiply
    /// i. else if '/' divide
    else if (optor == '/') res = res/inval;
    /// j. otherwise print error message
  } // end of main loop
} // end of main


Did you try dividing by zero, as I suggested at the bottom of the previous page?

If you made your result double, then you got "infinity" for a result. Multiply that by zero and you get "not a number" (sometimes abbreviated "NaN"). I was on the draft committee that created the standard by which every computer now manufactured now does its floating-point arithmetic, and strange-looking results like these were invented for the standard so that high-quality mathematical results could be possible. They didn't exist (I think one large mainframe had infinity, but noboy did NaN) 60 years ago. Berkeley Professor Kahan, whose math was the basis for the standard, could take a 12-digit calculator from the open market, and do a simple home mortgate calculation that was just plain wrong, off by I think dollars, because they did their rounding wrong. That kind of stuff.

But in my version above, I did the calculation in integer. Did you try that? What happens when you divide by zero in integer mode? Exception! Your program dies. If you follow the advice in my "Need to Know" page and wrap an empty try-catch around your program like this:

public static void main() {
  int inval = 0, res = 0;
  char optor;
  while (true) {
    try {
      /// a. display the current result (initially =0)
      ...
      /// j. otherwise print error message
    } // end of main loop
  } catch (Exception ex) {}
} // end of main
What happens now? Your program still dies, but you did it instead of the system. You can see that more clearly by having the catch command print something out:
} catch (Exception ex) {System.out.println("got exception " + ex.toString());}
 
Now put the try-catch inside the while-loop, like this:
public static void main() {
  int inval = 0, res = 0;
  char optor;
  while (true) {
    try {
      /// a. display the current result (initially =0)
      ...
      /// j. otherwise print error message
    } catch (Exception ex) {System.out.println("got exception " + ex.toString());}
  } // end of main loop
} // end of main
 
What happens when you divide by zero in this version? Your program didn't die, but it didn't do anything else. The purpose for exceptions is to let you decide what to do when there is some kind of mistake (either in the input, or possibly something else went wrong), and perhaps notify the user, or maybe take corrective action. The point is, your program will be valued more greatly if you do something reasonable when errors happen. Crash-and-burn may be reasonable for toy programs you write for your own use, but when you are getting paid for your work, you need to think about what the user wants done, and do that. It's an important part of programming.

If you looked inside my Zystem class, you probably saw that I liberally use empty try-catch code to basically throw the exceptions away. For this learning environment, that is exactly the right thing to do. Now you get to think about how to do it different, when you eliminate my Zystem class, coming up next .

Next: Java Input

<<Previous | ToC | Next >>

Revised: 2020 October 20