Link to home
Start Free TrialLog in
Avatar of gvijay1
gvijay1

asked on

Please explain this exception example

Experts,

I have these two scenarios, one compiles fine and the other does not. I am unable to figure out why. CustomException is just a class that extends java.lang.Exception.

public class ExceptionTest {
      public static void main(String args[]) throws CustomException{

            ExceptionTest m_test = new ExceptionTest();
            m_test.doTest();
      }
      
      public void testException() throws CustomException{            
            throw new CustomException();
      }
      
      public Vector doTest() throws CustomException{
            try{
                  testException();
            }catch(Exception e){
                  throw e;
            }
            finally{
                  return null;
            }
      }      
}

In the doTest method, I throw java.lang.Exception but do not need to declare that in my method. Declaring CustomException is sufficient. HOWEVER, when I change the doTest method to return void and remove the finally block, the compiler complains about declaring java.lang.Exception. Also, if I return a value from outside the finally block, I get the same compilation error.

Why is it that by simply specifying a return type and returning from the finally block, the compiler allows the code to be compiled? BTW, I am using IBM JDK 1.3, but I noticed this behavior from Sun JDK as well.
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Firstly if your method is throwing an exception, it should declare that it throws it.
The existance of the return in the finally block will result in the exception not actually getting thrown (by your method). That is why it compiles ok.
Avatar of aozarov
aozarov

I think since 1.4.? Sun compiler will omit a warning when you have a return statement from a finally block.
This is a bad practise as it will mask both thrown Exception or pervious returned values.
Your code is better structured like the following (though it won't compile because it does not declare that it can throw an Exception). So you also need to change the declararion to define that it may throw that Exception.


public class ExceptionTest {
     public static void main(String args[]) throws CustomException{

          ExceptionTest m_test = new ExceptionTest();
          m_test.doTest();
     }
     
     public void testException() throws CustomException{          
          throw new CustomException();
     }
     
     public Vector doTest() throws CustomException{  // <-- should be throws Exception
          Vector result = null;
          try{
               testException();
          }catch(Exception e){
               throw e;
          }
          finally{
              // add cleaup etc here, but don't return
          }
          return result;
     }    
}
Also, if you know that testException throws CustomException why do you catch Exception?
Are you trying to catch also RuntimeException in that block?

If you change the code to:
   try{
               testException();
          }catch(CustomException e){
             // apply some logic here (like log otherwise there is no point of catching it)
              throw e;
          }

then you can leave doTest() throws CustomException instead of having throws Exception.
> Also, if you know that testException throws CustomException why do you catch Exception?

The example does not appear to be functional code, just a test to determine why the compiler was allowing it.
Which is because the exception does in fact not get thrown, so it doesn't need to declare that it does.
objects, I realized that this is a test code to get better understanding on Java language.
I mentioned that to make a point clear as part of a "best practise" behaviour.
Avatar of gvijay1

ASKER

Objects,

You mentioned that the exception "does in fact not get thrown". I am not sure how the exception does not get throws just because I am returning the value from the finally block. The testException() method which is called actually throws the CustomException.

So, even after executing the finally block, doesn't the doTest method still throw the exception?
> even after executing the finally block, doesn't the doTest method still throw the exception?

no it doesn't, because you return from the finally block (which is executed after you throw the excepotion)
Avatar of gvijay1

ASKER

In my example, I have used a generic meaningless Exception. However, say an SQLException was throws by the JDBC driver - if I return a value from the finally block regardless of what it is, then the exception is ignored?

If this is true, would there be any practical reason to do the above?
>> if I return a value from the finally block regardless of what it is, then the exception is ignored?
Right.

>> If this is true, would there be any practical reason to do the above?
No, see my comment about Java compiler warning.
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
It is not only the exception that might be ingnored (when having return from finaly) it is also any previous returned value which will be ignored.
Issue arises because code in a finally block is guarnteed to be executed, so if you return inside it you lose any previously thrown exceptions or returns.
Avatar of gvijay1

ASKER

Thanks for the comments. It was very helpfull and informative.