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

流过昼夜 提交于 2020-01-06 18:07:48

问题


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?


回答1:


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




回答2:


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.




回答3:


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.




回答4:


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




回答5:


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.




回答6:


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




回答7:


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();
    }
}


来源:https://stackoverflow.com/questions/25280665/java-where-to-put-return-in-try-catch-finally-block

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!