finally throw return

小结:

1. 正常情况下finally语句中不应该使用return语句也不应该抛出异常

2. finally throw 覆盖之前的异常throw;永远在finally中放入绝对安全的代码(saturn java 热加载(一) )

3. finally return 覆盖之前的return

4. finally return 覆盖之前的异常throw

5. 线程的状态及interrupt 守护线程有可能不会执行finnaly块中的代码

6. try finally with no catch , which is suitable for case that sometimes we need to release some resources in the finally block, but meanwhile we wanna ignore the exception, just let it thrown up instead of catching it

 

对于第2点,时常发生:

        AbstractJdsJavaJob abstractJdsJavaJob = null;
        try {
            String [] temp = shardParam.split(";");
            String dir = "file:"+temp[0];
            URL url = new URL(dir);
            URL[] urls2 = {url};

            MyUrlClassLoader myUrlClassLoader = new MyUrlClassLoader(urls2);

            Class CA = myUrlClassLoader.findClass(temp[1]);
            abstractJdsJavaJob = (AbstractJdsJavaJob)CA.newInstance();

            abstractJdsJavaJob.runJdsJob(jobName, shardItem, shardParam);
            LOGGER.info("success:{},{},{}", jobName, shardItem, shardParam);
            return new SaturnJobReturn(Common.createJobResString("", jobName, shardItem, shardParam, true));

        } catch (Exception e) {
            LOGGER.info("error:{},{},{}", jobName, shardItem, shardParam);
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            new SendMailThread(new Date(), e, jobName, shardItem, shardParam).execute();
            throw new JdsFastJobException(e);
        } finally {
            abstractJdsJavaJob.release();
        }

 

finally中的null指针抛出异常,覆盖了原本应该打印的catch模块异常信息,同时覆盖了发邮件

 

 

java异常语句中的finally块通常用来做资源释放操作,如关闭文件、关闭网络连接、关闭数据库连接等。正常情况下finally语句中不应该使用return语句也不应该抛出异常,以下讨论仅限于java语言设计本身,正常编码时应避免。

finally块中使用return会覆盖method的返回值

以下代码的返回值为:1

复制代码
public static int div(){
        try {
            return 3;
        }catch (ArithmeticException e){
            System.out.println("catch in div");
            return 2;
        }
        finally {
            System.out.println("finally in div");
            return 1;
        }
    }
复制代码

以下代码的返回值同样是:1

复制代码
 public static int div(){
        try {
            return 3/0;
        }catch (ArithmeticException e){
            System.out.println("catch in div");
            return 2;
        }
        finally {
            System.out.println("finally in div");
            return 1;
        }
    }
复制代码

 

finally块中使用return会抑制异常的冒泡传输

即:只要finally中使用了return语句,调用者便认为该方法正常返回

以下代码的输出为

catch in div
finally in div
catch in adapter
finally in adapter

复制代码
/**
 * Created by Administrator on 2017/11/27.
 */

public class Test {

    public static void main(String[] args) {
        adapter();
    }

    public static void adapter() {
        try {
            div();
        } catch (ArithmeticException e) {
            System.out.println("catch in adapter");
        } finally {
            System.out.println("finally in adapter");
        }
    }

    public static int div() {
        try {
            int a = 5 / 0;
            return a;
        } catch (ArithmeticException e) {
            System.out.println("catch in div");
            throw e;  // 重新将异常抛出给调用者
        } finally {
            System.out.println("finally in div");
        }
    }
}
复制代码

 

 但如果在 div 的finally块中添加了return语句

复制代码
    public static int div(){
        try {
            int a =  5/0;
            return a;
        }catch (ArithmeticException e){
            System.out.println("catch in div");
            throw  e; // 重新将异常抛出给调用者,但是抛出会被忽略
        }
        finally {
            System.out.println("finally in div");
            return 1;
        }
    }
复制代码

则代码的输出为

catch in div
finally in div
finally in adapter

即:finally块中的return语句会阻止异常的栈调用传输,使caller认为该方法已经正常返回

 

finally块中的throw语句会覆盖try和catch语句中的异常

以下代码

复制代码
/**
 * Created by Administrator on 2017/11/27.
 */

public class Test {

    public static void main(String[] args) {
        adapter();
    }

    public static void adapter() {
        try {
            div();
        } catch (Exception e) {
            System.out.println(String.format("catch in adapter: %s",e.getMessage()));
        } finally {
            System.out.println("finally in adapter");
        }
    }

    public static int div() throws Exception{
        try {
            int a = 5 / 0;
            return a;
        } catch (ArithmeticException e) {
            System.out.println("catch in div");
            throw new Exception("Exception in div"); // 抛出新的异常
        } finally {
            System.out.println("finally in div");
            throw new Exception("Exception in Finally");  // 抛出新的异常
        }
    }
}
复制代码

输出是:

catch in div
finally in div
catch in adapter: Exception in Finally
finally in adapter

即,catch块中抛出的异常北finally块抛出的异常替换了

 

修改div方法为

复制代码
 public static int div() throws Exception{
        try {
            int a = 5 / 0;
            return a;
        }  finally {
            System.out.println("finally in div");
            throw new Exception("Exception in Finally");  // 抛出新的异常
        }
    }
复制代码

输出为:

finally in div
catch in adapter: Exception in Finally
finally in adapter

即,try块中捕获的异常北finally块抛出的异常替换

 

finally块和普通代码块一样,无法同时使用return语句和throw语句,因为无法通过编译

 

 
 

posted on 2018-11-21 10:23  silyvin  阅读(212)  评论(0编辑  收藏  举报