Reputation: 5758
I have the following code
public static void nocatch()
{
try
{
throw new Exception();
}
finally
{
}
}
Which gives the error
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Unhandled exception type CustomException
My Question is why was it designed that the catch block is optional, when there is no way of getting around not having a catch?
From finally()'s perspective, I understand that
finally
should have atleast a try
block, catch
is optional. The point of finally blocks is to make sure stuff gets cleaned up whether an exception is thrown or not. As per the JLS
A finally clause ensures that the finally block is executed after the try block and any catch block that might be executed, no matter how control leaves the try block or catch block.
Edit:
By adding a return in the finally block, compiler does not give the error WHY?!
public static void nocatch()
{
try
{
throw new Exception();
}
finally
{
return; //By adding this statement, the compiler error goes away! Please let me know why
}
}
Upvotes: 5
Views: 4002
Reputation: 1075905
My Question is why was it designed that the catch block is optional, when there is no way of getting around not having a catch?
Yes there is: Declare that the method throws the exception:
public static void nocatch() throws CustomException
{
try
{
throw new CustomException();
}
finally
{
}
}
try/finally
without catch
is to ensure that you clean up anything you need to clean up, even if you aren't handling the exception yourself. (Be sure not to allow any other exception to be thrown from within finally
, or you'll hide the primary exception.)
Here's an example to play with (live copy):
private static class CustomException extends Exception {
}
public static void main (String[] args) throws java.lang.Exception
{
try
{
System.out.println("Calling nocatch(false)");
nocatch(false);
}
catch (CustomException ce) {
System.out.println("Caught CustomException for false case");
}
try
{
System.out.println("Calling nocatch(true)");
nocatch(true);
}
catch (CustomException ce) {
System.out.println("Caught CustomException for true case");
}
}
public static void nocatch(boolean foo) throws CustomException
{
try
{
if (foo) {
System.out.println("Throwing");
throw new CustomException();
}
}
finally
{
System.out.println("In finally");
}
System.out.println("Reached outside the try/finally block");
}
Output:
Calling nocatch(false) In finally Reached outside the try/finally block Calling nocatch(true) Throwing In finally Caught CustomException for true case
As you can see, the finally
block's code runs regardless of whether an exception occurred, but the code after the try/finally
doesn't.
Re your follow-up asking why adding return
within the finally
makes the error go away:
try
{
throw new CustomException();
}
finally
{
return; // <=== Makes the compiler happy (but don't do it!)
}
Interesting edge case! It's because the code in the finally
block always runs, and so you'll always return rather than throw, hiding the exception that occurred. E.g., this is the sequence:
throw new CustomException()
throws the exception, which transfers control to the finally
block
Code in the finally
block issues a normal return from the method
This hides the fact the exception occurred; in effect, you've "handled" the exception (without actually handling it) via the finally
block. In general, this isn't a good idea; use catch
to handle exceptions, or declare them on the method so calling code can handle them.
Upvotes: 14