Reputation: 17454
Consider the following code snippet.
public static void main(String [] args) throws IOException
{
....
}
My assumption tells me that: Any exception be it arrayOutOfBoundsException
or IOException
, the program will get terminated since there is no catching of the exception (and the exception thrown is not general). However I do see people throws specific exception at the method signature.
My question: Is it redundant for doing this? (since any exception will cause the program to terminate)
If it is not redundant, what is the reason people do it do this way?
Upvotes: 1
Views: 1584
Reputation: 10086
main
method?the program will get terminated since there is no catching of the exception
It may seem that way because the main
method is where your program starts. But actually, the Java Virtual Machine (JVM) calls the main
method and therefore technically it catches and handles any exception thrown by it.
The handling done by JVM is merely to print the stack trace of the exception in the error stream, then terminate your program*. Which is why you see that stack trace in the console (unless the error stream was redirected elsewhere, like a file) before the program terminates.
* If no other programs (such as live non-daemon threads) are running in the JVM, it will also terminate itself.
However I do see people throws specific exception at the method signature. Is it redundant for doing this? (since any exception will cause the program to terminate)
First, I should clarify that by writing throws
, the programmer is not throwing the exception. The programmer is merely declaring that this exception may be thrown by the method, and a caller of the method must handle it in some way.
To take your example:
public static void main(String [] args) throws IOException
This is most likely added by the programmer because his program calls some method from another class that also declares this. Some common examples are:
public FileWriter(String fileName) throws IOException // a constructor can also throw exceptions
FileWriter.write(int c) throws IOException
The designer of this FileWriter
class has made it mandatory for its user (the programmer) to handle the IOException
. This is called a checked exception.
A checked exception tells the user that during the program run, the scenario causing this exception is likely to happen even though it normally shouldn't (because we don't live in an ideal world). This suggests an environmental error and such an exception can be thrown even in the best program.
The other type of an exception is the unchecked exception. The reason why you don't declare NullPointerException
(an unchecked exception) using throws
is because the scenario causing it is not expected to happen during a normal program run. If it happens, this suggests a programming error and a badly written program.
There are two ways to handle the exception received in a method.
First is the way the programmer has done in your example. Simply throw that exception back to the caller.
Second is to use a try-catch
block to handle it internally:
public static void main (String [] args) // no need to declare "throws IOException"
{
try {
/* some code here that may throw IOException */
} catch (IOException ioe) {
System.err.println("Uhhhh something went wrong!");
// or some logging can happen
ioe.printStackTrace();
System.exit(-6); // a custom error signal can be sent in termination
}
}
If it is not redundant, what is the reason people do it do this way?
They do it because Java forces checked exceptions to be handled explicitly, while unchecked exceptions can be left unhandled.
As I have already explained the two ways an exception can be handled, it should be noted that programmers may pick one way over another depending on the situation. For some methods it may make more sense to throw a caught exception to the caller, while for others it would make more sense to handle the caught exception internally.
Then there are those lazy programmers who just declares every checked exception with throws
.
Both checked and unchecked exceptions can be handled using either of the two ways above. Unchecked exceptions give you the third choice of not handling it, which in turn gives the caller the choice of handling or not handling it.
If you declare an unchecked exception using throws
, it will become a checked exception to the caller of your method.
You can also mix and match both ways. For example, you may handle a checked exception internally at any point in the method, even if it is declared to be thrown in the method signature. The throws
declaration will only take effect where the checked exception is not handled internally.
The main
method of a class can be called like any other regular static method in your program, just by passing in a String
array of arguments. It is only special in the sense that the JVM calls this method when the class is started as a Java program. When you manually call the main
method, you have to handle the checked exceptions that may be thrown.
Upvotes: 3
Reputation: 43391
If some code in main
throws a checked exception (like IOException
), you have to declare it in throws
. The main
method is just like a normal method in that regard (in fact, it's just like a normal method in all regards, except that it's also an entry point for the program).
Upvotes: 2