Users › 08 Exceptions
Throw and catch exceptions, understand finally, and
write your own exception classes.
An exception is any object that implements the _LANG.Exception
interface. That interface has default methods, so an implementer only needs the
three bindings:
%interface Exception
String getName() { return "Exception" }
String toString() { return "" }
int toInt() { return -1 }
Two exceptions are built in and thrown by the runtime:
IndexOutOfBoundsException (fields index and
length) and DivideByZeroException.
try {
int[] a = new int[3]
int x = a[9] // IndexOutOfBoundsException
} catch (IndexOutOfBoundsException e) {
// matched by class
} catch (Exception e) {
// matched by interface
} finally {
// always runs
}
throw takes a value whose type implements
Exception; throw new MyError(...) is the usual
form.catch clauses are tried in order; a concrete class
matches before the interface.finally follows Java's rules: it runs on normal completion,
on return/break/continue out of the
block, and while an exception propagates. A return inside
finally overrides the outer return value; an exception thrown
inside finally replaces the original one.%class com.example.MyError implements Exception
String _msg
int _code
void ___init(String msg, int code) {
this._msg = msg
this._code = code
}
String getName() Exception@getName {
return "MyError"
}
String toString() Exception@toString {
return "MyError: " + this._msg + ":" + this._code
}
int toInt() Exception@toInt {
return -2
}
The task-list example throws CapacityException when a bounded
list is full; the main program catches it and prints the message.
int parse(String s) throws (com.example.ParseError) {
...
}
throws goes after the interface bindings. It is documentation
only: the compiler does not enforce it.
If no catch matches, the exception reaches the top of the thread.
The runtime prints uncaught exception: <class name> and the thread ends;
for the main thread the process exits with code 1. A worker thread dying this way
does not stop the other threads (chapter 10).
%simple com.example.exc.Demo implements Main
#import Std
int run(int argc, String[] argv) Main@run {
int r = 0
try {
Std.print("try\n")
int[] a = new int[2]
int x = a[5]
Std.print("not reached\n")
} catch (IndexOutOfBoundsException e) {
Std.print("catch: ", e.getName(), " index=", e.index, " length=", e.length, "\n")
r = 1
} finally {
Std.print("finally\n")
}
try {
int z = 1 / (argc - argc)
Std.print("z=", z, "\n")
} catch (DivideByZeroException e) {
Std.print("div: ", e.getName(), "\n")
r = r + 1
}
return r == 2 ? 0 : 1
}
try
catch: IndexOutOfBoundsException index=5 length=2
finally
div: DivideByZeroException