I was playing around with some exception programs and came across something which i am surprised i never encountered before.
import java.io.*;
class ExceptionTest
{
public static void main(String[] args)
{
try
{
System.out.println("hello");
}
catch(IOException ioe)
{
System.err.println("ioexception was thrown!!");
}
}
}
this raises an compiler error:
ExceptionTest.java:10: exception java.io.IOException is never thrown in body of
corresponding try statement
catch(IOException ioe)
^
1 error
My question is why is it like that?
Why is the compiler worried about a piece of code it is sure it would never reach. It could have just been a warning instead of a full-fledged error. Afterall we could want to keep the catch block as a backup for some future changes we might make or maybe the programmer just forgot to remove it after some edits.
I know i know it saves us from unnecessary keystrokes etc. etc. But it shouldn't bother compiler that much to raise an error. Or is there some other reason for this??
Also an IOException catch block in the code produces an compiler error but an Exception catch block does not... why is that?? Thnx in advance!!
Because the Java designers thought the system should help in this way. It's the same situation as this:
public class EarlyReturn {
public void foo() {
return;
System.out.println("Hi");
}
}
...which also results in a compile-time error. Code which will never be run is a bad thing, and the compiler helps us by letting us know it will never run, and the designers felt it should be an error rather than a warning.
You can change your code to catch Exception
rather than IOException
if you like, but although that would make the compiler let you do it, you'd still have code that would never be run (which, again, is a bad thing).
Also an
IOException
catch block in the code produces an compiler error but anException
catch block does not... why is that??
IOException
is a checked exception, and only checked exceptions are checked in this way (that's why they're called that). There are checked exceptions, unchecked exceptions (RuntimeException
and its subclasses), and errors (Error
and its subclasses). Technically, checked exceptions are all exceptions that aren't unchecked exceptions or errors (Section 11.1.1 of the JLS), but — this is a bit of a dark corner — not all checked exceptions are checked. Specifically, checked exceptions are checked unless they're Exception
or a superclass of it. From Section 11.2.3 of the JLS:
It is a compile-time error if acatch
clause can catch checked exception classE1
and it is not the case that thetry
block corresponding to thecatch
clause can throw a checked exception class that is a subclass or superclass ofE1
, unlessE1
isException
or a superclass ofException
.
The entirety of Section 11 is probably worth a read. As you can guess, this is a part of Java that evolved a fair bit in the early days, resulting in this somewhat convoluted definition of what gets checked.