Juneyoung Oh
Juneyoung Oh

Reputation: 7652

java - where to put "return" in try, catch, finally block?

I was tracking Spring Framework source and found some code which is not friendly to me. I thought I have to put "return" statement in finally block, but this code put that in try block.

Here is the source code.(This is part of org.springframework.jdbc.core.JdbcTemplate)

  629       public <T> T query(
  630               PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor<T> rse)
  631               throws DataAccessException {
  632   
  633           Assert.notNull(rse, "ResultSetExtractor must not be null");
  634           logger.debug("Executing prepared SQL query");
  635   
  636           return execute(psc, new PreparedStatementCallback<T>() {
  637               public T doInPreparedStatement(PreparedStatement ps) throws SQLException {
  638                   ResultSet rs = null;
  639                   try {
  640                       if (pss != null) {
  641                           pss.setValues(ps);
  642                       }
  643                       rs = ps.executeQuery();
  644                       ResultSet rsToUse = rs;
  645                       if (nativeJdbcExtractor != null) {
  646                           rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
  647                       }
  648                       return rse.extractData(rsToUse);
  649                   }
  650                   finally {
  651                       JdbcUtils.closeResultSet(rs);
  652                       if (pss instanceof ParameterDisposer) {
  653                           ((ParameterDisposer) pss).cleanupParameters();
  654                       }
  655                   }
  656               }
  657           });
  658       }

As you can see at line 648, it returns value in try block. and nothing more in finally block. I do not know how could this work?

Upvotes: 0

Views: 2700

Answers (7)

JaskeyLam
JaskeyLam

Reputation: 15755

Put the return in the try block, and put something really important(such as unlock the lock or close the db connection) after the logic is done in the finally block.

You don't even have to have catch block, here is one case that may help:

int releasePermitAndGet() {
    try{
        mLock.lock();
        mPermits++;//release the permit
        permitNotZero.signalAll();// signal the other thread that the conditon has been  changed.
    return mPermites;

}
    finally{
        mLock.unlock();
    }
}

Upvotes: 0

Ilya
Ilya

Reputation: 29693

Simple example to show, how finally works

try
{
   System.out.println("Inside try/catch");
   return 1;
}
finally
{
   System.out.println("Inside finally");
} 

will print

Inside try/catch
Inside finally  

And next code with return in try/catch

try
{
   if (true)
   { 
      throw new RuntimeException();
   }
   System.out.println("Inside try/catch");
   return 1;
}
finally
{
   System.out.println("Inside finally");
}  

will print Inside finally despite an exception. Method will throw exception

And next code with return in finally

try
{
   if (true)
   {
      throw new RuntimeException();
   }
   System.out.println("Inside try/catch");
}
finally
{
   System.out.println("Inside finally");
   return 2;
}

Will print Inside finally and method will return 2 and doesn't throw exception

Upvotes: 0

Sanjay Rabari
Sanjay Rabari

Reputation: 2081

Your finally block should not return resultset

you can write in finally block such Statements that are unconditionally executed after all other error processing has occurred and clean up of some resources.

IF Everything goes fine it return resultset from try block. and finally will execute.

If something went wrong some exception though finally runs but not returning resultset because If its not generated, it doesnt make sense to return some null value.

Upvotes: 1

schlagi123
schlagi123

Reputation: 735

I think you should have a return in the try and in the catch, or you save the returnvalue in a variable and return it after the try-catch-finally-block or in the finally-block.

You should not have return-statements in try and finally or catch and finally. The finally overrides the return of the try or catch:

e.g.

private static String getString() {
  try{
    return "a";
  } finally {
    return "b";
  }
}

This returns b

Upvotes: 1

Maroun
Maroun

Reputation: 95968

See the JLS - 14.20.2. Execution of try-finally and try-catch-finally, best source ever:

If execution of the try block completes abruptly for any other reason R, then the finally block is executed, and then there is a choice:

If the finally block completes normally, then the try statement completes abruptly for reason R.

If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

You can return in the finally, this will override the other return value in try.

Upvotes: 1

Scary Wombat
Scary Wombat

Reputation: 44844

In a try finally the finally will still get called even though the try has returned

In you code, it is desirable for all of the code in the finally block to be called, so no return makes sense.

Upvotes: 0

hcl
hcl

Reputation: 64

Even if you put return in try block, java will still execute the finally block before executing the return statement in try block.

Upvotes: 0

Related Questions