trycatchfinally详解+⽰例
前⾔
关于try/catch/finally的组合相信有⼀点Java基础的⼈都知道,但是关于其真正的执⾏顺序不要⾃以为很了解,先来看看下⾯⼏个例⼦就知道了。
举例
例1
public class Test3 {
public static void main(String[] args) {
try {
System.out.println("");
return;
} finally {
System.out.println("");
}
}
}
结果为:
<
<
这个⼤家都知道,在try中的return真正返回之前会执⾏finally中的语句。
例2
public class Test3 {
public static void main(String[] args) {
System.out.println("" + getValue());
}
public static int getValue() {
try {
System.out.println("");
return0;
} finally {
System.out.println("");
return1;
}
}
}
结果为:
<
<
main (1)
此处在执⾏finally中语句的时候,return 1;返回了,所以try中的return语句不会得到执⾏。
例3
public static int getValue() {
int i = 0;
try {
System.out.println("");
return i;
} finally {
System.out.println("");
i++;
}
}
}
结果为:
<
<
main 0
这个很多⼈都不知道为什么了,按道理说,在try的return执⾏之前,在finally之中已经更改了i的值,为什么return的值任然是0⽽不是1呢?
实际上,Java 虚拟机会把 finally 语句块作为 subroutine(对于这个 subroutine 不知该如何翻译为好,⼲脆就不翻译了,免得产⽣歧义和误解。)直接插⼊到 try 语句块或者 catch 语句块的控制转移语句之前。但是,还有另外⼀个不可忽视的因素,那就是在执⾏subroutine(也就是 finally 语句块)之前,try 或者 catch 语句块会保留其返回值到本地变量表(Local Variable Table)中。待subroutine 执⾏完毕之后,再恢复保留的返回值到操作数栈中,然后通过 return 或者 throw 语句将其返回给该⽅法的调⽤者(invoker)。
所以,上例中try中返回的不是finally中的i,⽽是在执⾏finally之前放在本地变量表中的i。所以返回的仍然是0。
例4
public class Test3 {
public static void main(String[] args) {
System.out.println("" + getValue());
}
public static int getValue() {
int i = 0;
try {
System.out.println("");
} finally {
System.out.println("");
i++;
return i;
}
}
}
结果为:
<
<
main (1)
由于try中没有返回语句,所以不会将try中的i放到本地变量表,执⾏完finally之后也不会再返回try,⽽是使⽤finally中的i直接返回。例5
public static int getValue() {
int i = 0;
try {
System.out.println("");
return i;
} finally {
System.out.println("");
i++;
return i;
}
}
}
结果为:
<
<
main (1)
虽然try在执⾏finally之前将返回值保存到了本地变量表,但是finally中的i是另外⼀个副本,被finally操作后直接返回,不再回到try 中,所以try中的i⽆法恢复。
例6
public class Test3 {
public static void main(String[] args) {
System.out.println("" + getValue());
}
public static int getValue() {
int i = 0;
try {
System.out.println("");
} finally {
System.out.println("");
i++;
}
return i;
}
}
结果为:
<
<
main (1)
因为try中没有return语句,所以在执⾏finally之前不会存放i到本地变量表,也不会再返回到try。
例7
public static int getValue() {
int i = 0;
try catch的使用方法try {
System.out.println("");
return test();
} finally {
System.out.println("");
i++;
}
}
public static int test() {
System.out.println("");
return10;
}
}
结果为:
<
<
<
main (10)
此处try中的return test()就等同于int r = test();return r;,另外,catch和finally的关系和上⾯是⼀样的,这⾥省略了。最佳实践
1)不要在catch和finally块中有return语句;
2)建议在finally中只进⾏资源的清理操作。
参考
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论