The previous section showed how to write an exception handler for the writeList
method in the ListOfNumbers
class. Sometimes, it's appropriate for code to catch exceptions that can occur within it. In other cases, however, it's better to let a method further up the call stack handle the exception. For example, if you were providing the ListOfNumbers
class as part of a package of classes, you probably couldn't anticipate the needs of all the users of your package. In this case, it's
better to not catch the exception and to allow a method further up the call stack to handle it.
If the writeList
method doesn't catch the checked exceptions that can occur within it, the writeList
method must specify that it can throw these exceptions. Let's modify the original writeList
method to specify the exceptions it can throw instead of catching them. To remind you, here's the original version of the writeList
method that won't compile.
public void writeList[] { PrintWriter out = new PrintWriter[new FileWriter["OutFile.txt"]]; for [int i = 0; i < SIZE; i++] { out.println["Value at: " + i + " = " + list.get[i]]; } out.close[]; }
To specify that
writeList
can throw two exceptions, add a throws
clause to the method declaration for the writeList
method. The throws
clause comprises the throws
keyword followed by a comma-separated list of all the exceptions thrown by that method. The clause goes after the method name and argument list and before the brace that defines the scope of the method; here's an example.
public void writeList[] throws IOException, IndexOutOfBoundsException {
Remember that IndexOutOfBoundsException
is an unchecked exception; including it in the throws
clause is not mandatory.
You could just write the following.
public void writeList[] throws IOException {
When talking about Exceptions in Java, only 2 main types are invoked: checked exceptions and unchecked exceptions.
The checked exceptions are checked in compile time: if you don't handle a checked exception [by using a try/catch block for example or the throws key word], the compiler will raise an error, in other words, it won't let you build your program, this is why you should always handle all the checked exceptions.
The unchecked exceptions are checked in runtime: your compiler will not raise an error if you don't handle these type of exceptions.
Now the question is: how can i distinguish between these two types when i am coding ?
You should first keep in mind that every exception in java should inherits from the "Exception" class.
Now, there is a simple way you can tell a unchecked exception from a checked one: any exception class that inherits from "RuntimeException" is considered an unchecked exception, and any class that inherits from "Exception" but not "RuntimeException" is considered is a checked exception.
In your case, the method you're invoking throws a ArithmeticException
and a NullPointerException
. But this
two exceptions inherits from the "RuntimeException". So, according to the rule written above, these 2 exceptions are unchecked exceptions, and that's why you had no need to handle it when invoking your method myMethod[]
.
Checking that thrown objects are caught
A Java compiler checks to make sure that certain thrown objects are caught by your program; if they are not caught, the compiler issues an error message and refuses to compile the program. For example, consider this method main:
public static void main[String[] args] {
throw new Exception[];
}
[This method is useless ---except to illustrate our point.] Upon attempting to compile this method, the compiler issues this error message:
Error: Exception java.lang.Exception must be caught or
it must be declared in the throws clause of this method.
You can get rid of this message by using a try-statement that catches the thrown object [again, this is a useless program except to illustrate our point]. But don't do this simply to have an exception ignored! If your program cannot reasonably handle a thrown exception, don't use the following trick to get rid of it.
public static void main[String[]] {
try {
throw new Exception[];
} catch {Exception ex] {
...
}
}
Instead, use a throws-clause, as explained below. But before we explain the throws-clause, we talk about checked and unchecked objects.
Checked and unchecked objects
Checking that thrown objects are caught is a good idea, for it forces the programmer to think carefully about how thrown objects should be handled. But the Java compiler does not check ALL thrown objects in this manner. Checking all possible thrown objects would be awkward and cumbersome, for there are many possibilities. For example, there are many possible RuntimeExceptions like divide-by-0, index-out-of-bounds, and null-pointer-exception.
Java checks all of throwable classes EXCEPT:
- Thrown objects of class Error and its subclasses
- Thrown objects of class RuntimeException and its subclasses
The throws clause
The throws clause has the form
throws , ...,
where each class-name is Throwable or one of its subclasses. Placing a throws clause on a method relieves the method of the responsibility of catching objects of the named classes and places the responsiblity on any method that calls this one.
Here's a suggestion. Don't worry about putting in throws clauses. Put them out of your mind. But, whenever Javatells you that an exception must be caught, put in the throws clause.
©This material is from the CD ProgramLive by David Gries and Paul Gries