Attempting Risky Code - try and catch

Contact Us or call 1-877-932-8228
Attempting Risky Code - try and catch

Attempting Risky Code - try and catch

If a method is going to resolve a potential exception internally, the line of code that could generate the exception is placed inside a try block.

  • There may be other code inside the try block, before and/or after the risky line(s). Any code that depends upon the risky code's success should be in the try block, since it will automatically be skipped if the exception occurs.
try {
	risky code code that depends on the risky code succeeding
}

There is usually at least one catch block immediately after the try block. A catch block must specify what type of exception it will catch.

catch (xceptionClassName exceptionObjectName) {
	code using methods from exceptionObjectName
}
  • There can be more than one catch block, each one marked for a specific exception class.
  • The exception class that is caught can be any class in the exception hierarchy, either a general (base) class, or a very specific (derived) class.
  • The catch block(s) must handle all checked exceptions that the try block is known to throw unless you want to throw that exception back to the method that called this one.
  • It is possible to have a try block without any catch blocks if you have a finally block, but any checked exceptions still need to be caught, or the method needs to declare that it throws them. We will cover finally later in this section.

If an exception occurs within a try block, execution jumps to the first catch block whose exception class matches the exception that occurred (using an instanceof test). Any steps remaining in the try block are skipped.

If no exception occurs, then the catch blocks are skipped. The catch blocks will also be skipped if an exception that is not caught occurs, such as a RuntimeException, or an exception that the method declared it throws.

You cannot catch an exception that would not occur in the try block, but you can mark a method as throwing an exception that it doesn't (this leaves open the possibility that an extending class can override the method and actually throw the exception).

Notes on try ... catch Blocks and Variable Scope/Initialization

If you declare a variable within a try block, it will not exist outside the try block, since the curly braces define the scope of the variable. You will often need that variable later, if nowhere else other than the catch or finally blocks, so you would need to declare the variable before the try.

If you declare but don't initialize a variable before a try block, and the only place you set a value for that variable is in the try block, then it is possible when execution leaves the try ... catch structure that the variable never received a value.

  • So, you would get a "possibly uninitialized value" error message from the compiler, since it actually keeps track of that sort of thing.
  • Usually this happens with object references; you would generally initialize them to null.

Code Sample:

Java-Exceptions/Demos/ExceptionTest.java
public class ExceptionTest {
  public static void main(String[] args) {
    int i, j, x = 5, y = 5, z = 0;
    try {
      i = x/y;
      System.out.println("x/y = " + i);
      j = x/z;
      System.out.println("x/z = " + j);
    }
    catch(ArithmeticException e) {
      System.out.println("Arithmetic Exception!");
    }
    System.out.println("Done with test");
  }
}

The program will print the first result, then fail while performing the division for the second equation. Execution will jump to the catch block to print our message on the screen.

Note: ArithmeticException is one of the few you are not required to catch, but you can still catch it if you wish.

Example - An Exception You Must Handle

The preceding example used a RuntimeException which your code is not obligated to handle.

Most methods in the I/O classes throw IOException which is an exception you must handle.

Our KeyboardReader class has try and catch to handle this, essentially stifling the exception, since it is unlikely, if not impossible, to actually get an IOException from the keyboard.

Code Sample:

Java-Exceptions/Demos/IOExceptionTest.java
import java.io.IOException;

public class IOExceptionTest {
  
  public static void main(String[] args) {
    
    int num = 0;
    
    num = System.in.read(); // comment out this line
    
    try {
      num = System.in.read();
      System.out.println("You entered " + (char) num);
    }
    catch (IOException e) {
      System.out.println("IO Exception occurred");
    }
  } 
}

The line marked to comment out throws IOException, but is not in a try block, so the compiler rejects it. The second read attempt is within a try block, as it should be.

  • Ttry to compile this code as is and then comment out the indicated line.
  • There is no way we can force an IOException from the keyboard to test the catch block.

Using Multiple catch Blocks

It is possible that a statement might throw more than one kind of exception. You can list a sequence of catch blocks, one for each possible exception. Remember that there is an object hierarchy for exceptions. Since the first one that matches is used and the others skipped, you can put a derived class first and its base class later (you will actually get a compiler error if you list a more basic class before a derived class, as it is "unreachable code").

Code Sample:

Java-Exceptions/Demos/MultiCatchTest.java
import util.KeyboardReader;

public class MultiCatchTest {
  public static void main(String[] args) {
    int num1, num2;
    try {
      num1 = KeyboardReader.getPromptedInt("Enter a number: ");
      num2 = KeyboardReader.getPromptedInt("Enter another number: ");
      System.out.println(num1 + " / " + num2 + " = " + num1/num2);      
    }
    catch (NumberFormatException e) {
      System.out.println("Number Format Exception occurred");
    }
    catch (ArithmeticException e) {
      System.out.println("Divide by Exception occurred");
    }
    catch (Exception e) {
      System.out.println("General Exception occurred");
    }
  } 
}

The code in the try block could throw NumberFormatException during the parsing, and ArithmeticException while doing the division, so we have catch blocks for those specific cases. The more generic catch block for Exception would catch other problems, like NullPointerException.

Next