不用太多复杂的例子和解释,这里几个小例子大家就能懂。
eg1:
代码语言:javascript复制public class Test {
public static void main(String[] args) {
System.out.println("开始");
int num = 10;
System.out.println(test(num));
}
public static int test(int b) {
try {
b = 10; // 这里b变成了20
return b = 10; // 先执行return后面的表达式,b变成了30,表达式的值临时存储起来再去执行finally
} catch (Exception e) {
return 1;
} finally {
System.out.println("===" b); // 30
b = 10; // 40
return b; // 返回40
}
}
}
打印结果:
开始 ===30 40
注意点:
try
代码块中,return
后面的表达式先执行再把值临时存储起来。接着执行finally
代码块,执行完finally
代码块后再去执行try
代码块中的return
。如果finally
代码块中有return
,那么就直接返回了,不会让try
代码块中return
返回。
eg2:(相比上一个例子区别仅为finally
里没有return
)
public class Test {
public static void main(String[] args) {
System.out.println("开始");
int num = 10;
System.out.println(test(num));
}
public static int test(int b) {
try {
b = 10; // 这里b变成了20
return b = 10; // 先执行return后面的表达式,b变成了30,表达式的值临时存储起来再去执行finally
} catch (Exception e) {
return 1;
} finally {
System.out.println("===" b); // 30
b = 10; // 40
}
}
}
运行结果:
开始 ===30 30
注意点:
即使finally
代码块中b的值更改了,但是没有return
返回,而try
代码块中return
的是上一次临时保存值30
,所以最后返回打印30
需要注意的是,如果是引用类型,结果那就不一样了。
代码语言:javascript复制public class Test {
public static void main(String[] args) {
System.out.println("开始");
StringBuilder str = new StringBuilder("a");
System.out.println(test(str));
}
public static StringBuilder test(StringBuilder s) {
try {
s.append("b"); // 这里s变成了"ab"
return s.append("c"); // 先执行return后面的表达式,s变成了"abc",表达式的值临时存储起来再去执行finally,
// 但是,这里临时保存的是引用!!在finally改变引用地址的值
} catch (Exception e) {
return null;
} finally {
System.out.println("===" s); // "abc"
s.append("d"); // s引用地址的值改为了"abcd"
}
}
}
运行结果:
开始 ===abc abcd
常用的需要记住的就这几个,如果有人问你catch
里面再套几层try-catch-finally
之类的。谁吃的这么饱啊,这个就和i i i i i ...
一样无聊,不过finally
最后都会一层层执行,推断和实验结果没有什么差异。
来看看你可能想知道的无聊的例子。
代码语言:javascript复制public class Test {
public static void main(String[] args) {
System.out.println("开始");
StringBuilder str = new StringBuilder("a");
System.out.println(test(str));
}
public static StringBuilder test(StringBuilder s) {
try {
s.append("b");
int bb = 1 / 0; // 制造运行时异常
return s.append("c");
} catch (Exception e) {
try {
throw new RuntimeException(" run error");
} catch (Exception e1) {
System.out.println("catch!!");
} finally {
int b = 1 / 0; // 制造运行时异常
// System.exit(0);
System.out.println("!!!");
}
} finally {
System.out.println("===" s);
s.append("d");
}
return null;
}
}
运行结果:
记住finally
不是一定执行,比如System.exit(0)
后虚拟机退出,所有的finally
都不执行,嵌套finally
也没用,直接终止执行程序。
finally
块中发生了异常而你没有捕捉,那么该finally
块后面的代码就不会继续执行,如果外层还有finally
,那么外层finally
块是会执行的。
如果还有我没有讲到的,欢迎大家提问。
面试和笔试无非就是这些东西,难道还有更无聊的题?