try,catch,finally

public class TryCatchFinally {
    public static final String test() {
        String t "";
        try {
            t "try";
            return t;
        } catch (Exception e) {
            // result = "catch";
            t = "catch";
            return t;
        } finally {
            t "finally";
        }
    } 
    public static void main(String[] args) {
        System.out.print(TryCatchFinally.test());
    }
}

输出try

通过字节码,我们发现,在try语句的return块中,return 返回的引用变量(t 是引用类型)并不是try语句外定义的引用变量t,而是系统重新定义了一个局部引用t1,这个引用指向了引用t1对应的值,也就是try ,即使在finally语句中把引用t指向了值finally,因为return的返回引用已经不是t ,所以引用t的对应的值和try语句中的返回值无关了。

public class TryCatchFinally {
    public static final String test() {
        String t = "";
        try {
            t = "try";
            return t;
        } catch (Exception e) {
            // result = "catch";
            t = "catch";
            return t;
        } finally {           
            t = "finally";
            return t;
        }
    } 
    public static void main(String[] args) {
        System.out.print(TryCatchFinally.test());
    }
}

输出finally

字节码文件会显示,直接忽略try里面的return,起作用的是finally里面的return

public class TryCatchFinally {
    public static final String test() {
        String t = "";
        try {
            t = "try";
            Integer.parseInt(null);
            return t;
        } catch (Exception e) {
            // result = "catch";
            t = "catch";
            return t;
        } finally {           
            t = "finally";
        }
    } 
    public static void main(String[] args) {
        System.out.print(TryCatchFinally.test());
    }
}

输出catch

try语句里面会抛出 java.lang.NumberFormatException,所以程序会先执行catch语句中的逻辑,t赋值为catch,在执行return之前,会把返回值保存到一个临时变量里面t ',执行finally的逻辑,t赋值为finally,但是返回值和t',所以变量t的值和返回值已经没有关系了,返回的是catch

public class TryCatchFinally {
    public static final String test() {
        String t = "";
        try {
            t = "try";
            Integer.parseInt(null);
            return t;
        } catch (Exception e) {
            // result = "catch";
            t = "catch";
            return t;
        } finally {           
            t = "finally";
            return t;
        }
    } 
    public static void main(String[] args) {
        System.out.print(TryCatchFinally.test());
    }
}

输出finally

由于try语句里面抛出异常,程序转入catch语句块,catch语句在执行return语句之前执行finally,而finally语句有return,则直接执行finally的语句值,返回finally

public class TryCatchFinally {
    public static final String test() {
        String t = "";
        try {
            t = "try";
            Integer.parseInt(null);
            return t;
        } catch (Exception e) {
            t = "catch";
            Integer.parseInt(null);
            return t;
        } finally {           
            t = "finally";
        }
    } 
    public static void main(String[] args) {
        System.out.print(TryCatchFinally.test());
    }
}

在catch语句块添加了Integer.parser(null)语句,强制抛出了一个异常。然后finally语句块里面没有return语句。继续分析一下,由于try语句抛出异常,程序进入catch语句块,catch语句块又抛出一个异常,说明catch语句要退出,则执行finally语句块,对t进行赋值。然后catch语句块里面抛出异常。结果是抛出java.lang.NumberFormatException异常

public class TryCatchFinally {
    public static final String test() {
        String t = "";
        try {
            t = "try";
            Integer.parseInt(null);
            return t;
        } catch (Exception e) {
            t = "catch";
            Integer.parseInt(null);
            return t;
        } finally {           
            t = "finally";
            return t;
        }
    } 
    public static void main(String[] args) {
        System.out.print(TryCatchFinally.test());
    }
}

输出finally

这个例子里面finally 语句里面有return语句块。try catch中运行的逻辑和上面例子一样,当catch语句块里面抛出异常之后,进入finally语句快,然后返回t。则程序忽略catch语句块里面抛出的异常信息,直接返回t对应的值 也就是finally。方法不会抛出异常

public class TryCatchFinally {
    public static final String test() {
        String t = "";
        try {
            t = "try";
            Integer.parseInt(null);
            return t;
        } catch (NullPointerException e) {
            t = "catch";
            return t;
        } finally {           
            t = "finally";
        }
    } 
    public static void main(String[] args) {
        System.out.print(TryCatchFinally.test());
    }
}

catch语句里面catch的是NPE异常,而不是java.lang.NumberFormatException异常,所以不会进入catch语句块,直接进入finally语句块,finally对s赋值之后,由try语句抛出java.lang.NumberFormatException异常。

public class TryCatchFinally {
    public static final String test() {
        String t = "";
        try {
            t = "try";
            Integer.parseInt(null);
            return t;
        } catch (NullPointerException e) {
            t = "catch";
            return t;
        } finally {           
            t = "finally";
            return t;
        }
    } 
    public static void main(String[] args) {
        System.out.print(TryCatchFinally.test());
    }
}

try语句执行完成执行finally语句,finally赋值s 并且返回s ,最后程序结果返回finally

public class TryCatchFinally {
    public static final String test() {
        String t = "";
        try {
            t = "try";
            Integer.parseInt(null);
            return t;
        } catch (Exception e) {
            t = "catch";
            return t;
        } finally {           
            t = "finally";
            String.valueOf(null);
            return t;
        }
    } 
    public static void main(String[] args) {
        System.out.print(TryCatchFinally.test());
    }
}

对finally语句中添加了String.valueOf(null), 强制抛出NPE异常。首先程序执行try语句,在返回执行,执行finally语句块,finally语句抛出NPE异常,整个结果返回NPE异常。

 

总结:

1  try、catch、finally语句中,如果只有try语句有return返回值,此后在catch、finally中对变量做任何的修改,都不影响try中return的返回值。

2、try、catch中有返回值,而try中抛出的异常恰好与catch中的异常匹配,则返回catch中的return值。

3  如果finally块中有return 语句,则返回try或catch中的返回语句忽略。

4  如果finally块中抛出异常,则整个try、catch、finally块中抛出异常.并且没有返回值。

 

所以在使用try、catch、finally语句块时需要注意以下几点:

1 尽量在try或者catch中使用return语句。通过finally块中达到对try或者catch返回值修改是不可行的。

2 finally块中避免使用return语句,因为finally块中如果使用return语句,会显示的忽略掉try、catch块中的异常信息,屏蔽了错误的发生。

3 finally块中避免再次抛出异常,否则整个包含try语句块的方法回抛出异常,并且会忽略掉try、catch块中的异常。

posted @ 2019-08-15 22:04  LeeJuly  阅读(107)  评论(0)    收藏  举报