Recover in Fortress
Java makes it possible to catch exceptions, which is similar to recovering from a panic. By using a try-catch
block, we can prevent an exception from crashing the program and allow it to continue execution instead.
An example of where this can be useful: a server wouldn’t want to crash if one of the client connections exhibits a critical error. Instead, the server would want to close that connection and continue serving other clients. In fact, this is what Java’s javax.servlet
does by default for HTTP servers.
import java.util.Random;
public class ExceptionHandling {
// This method throws an exception
public static void mayThrow() throws Exception {
throw new Exception("a problem");
}
public static void main(String[] args) {
// try-catch must be used to handle exceptions
// When the enclosed code throws an exception,
// the catch block will execute and handle the exception
try {
mayThrow();
} catch (Exception e) {
// The caught exception is available as the variable e
System.out.println("Caught. Exception:\n " + e.getMessage());
}
// This code will run, because the exception was caught
System.out.println("After mayThrow()");
}
}
To run the program:
$ javac ExceptionHandling.java
$ java ExceptionHandling
Caught. Exception:
a problem
After mayThrow()
In this Java example, we use a try-catch
block to handle exceptions, which is analogous to using defer
and recover
in other languages. The mayThrow
method throws an exception, which is then caught in the main
method.
The key differences are:
- Java uses checked exceptions, which must be declared in the method signature or caught.
- Instead of deferring a function with a recover call, we directly wrap the potentially exception-throwing code in a try block.
- The catch block specifies what type of exception it handles, and provides direct access to the exception object.
Unlike some other languages where execution might stop at the point of the panic, in Java, once an exception is caught, the program continues execution after the try-catch block. This is why “After mayThrow()” is printed.