Finally
Java 中的 Finally 关键一般与try一起使用,在程序进入 try 块之后,无论程序是因为异常而中止或其它方式返回终止的,finally 块的内容一定会被执行 。
直接进行实验如下
1.一般情况
public static void returnTest(){
try{
System.out.println("I am try");
}
finally{
System.out.println("I am finally");
}
}
I am try
I am finally
- 语句顺序执行
- finally 也执行
2.加入return语句
static int i = 0;
public static int returnTest(){
try{
System.out.println("I am try");
return i + 1;
}
finally{
System.out.println("I am finally");
return i + 2;
}
}
public static void main(String []args) {
System.out.println(returnTest());
}
I am try
I am finally
2
调试结果:
- 语句顺序执行
- 程序进入 try 块后,return执行后finally仍执行
3.抛出异常
static int i = 1;
public static int returnTest(){
try{
System.out.println("I am try");
i = i / 0;
return i + 1;
}
catch(Exception e){
System.out.println("Exception");
return i + 2;
}
finally{
System.out.println("I am finally");
return i + 3;
}
}
public static void main(String []args) {
System.out.println(returnTest());
}
I am try
Exception
I am finally
4
调试结果:
执行 i = i / 0 之后转入 catch, 执行return i++;
转入finally,执行return i++
- 语句顺序执行
- 程序进入 try 块后,出现异常跳出 try 执行 catch
- finally 语句块在 catch 中的 return 语句之前执行
- finally 语句块的 return 屏蔽了catch 中的 return
为什么会这样呢?
4.
static int i = 1;
public static int returnTest(){
try{
System.out.println("I am try");
return i + 1;
}
catch(Exception e){
System.out.println("Exception");
return i + 2;
}
finally{
System.out.println("I am finally");
i++;//运行至此处i值为1
return i + 3;
}
}
public static void main(String []args) {
System.out.println(returnTest());
}
I am try
I am finally
5
结果是5
- 顺序运行至try 的 return 时并未跳过
- finally 的return执行后结束程序
5.
public static String returnTest(){
try{
System.out.println("I am try");
return foo("try-return");
}
finally{
System.out.println("I am finally");
return foo("finally-return");
}
}
public static String foo(String str){
System.out.println(str);
return str;
}
public static void main(String []args) {
System.out.println(returnTest());
}
I am try
try-return
I am finally
finally-return
finally-return
- 最终返回的仍是finally的return
- 但 try自己的return依然执行了
6.验证5
static int i = 0;
public static int returnTest(){
try{
System.out.println("I am try");
return i++;
}
finally{
System.out.println("I am finally");
return i + 2;
}
}
I am try
I am finally
3
- return的确被执行,但不是最终返回值
7.不return呢?
static int i = 1;
public static int returnTest(){
try{
System.out.println("I am try");
return ++i + 1;
}
finally{
System.out.println("I am finally");
i++;
}
}
I am try
I am finally
3
逐步调试发现:
- 执行try的return之后再执行finally 语句
- 执行finally 语句再执行try的return.但返回的结果是上次执行return的结果
执行顺序
无异常:
- 执行try的语句块
- 执行try的return语句,只执行表达式,将结果暂存,不返回
- 执行finally的语句块
如果finally有return 直接执行return, 返回finally的return,结束
如果finally无return 再次执行try的return,但返回首次执行结果,结束
可以把return当成一条普通表达式正常执行
有异常:
- 执行try的语句块
- 转至catch,再执行finally,try的return永远不会执行.
总结
finally 语句块在 try 中的 return 语句之前执行不准确,应是之间
- try的return仅在出现异常时不执行.
- finally的return会覆盖之前的return
- 无异常return先于finally执行,最终返回值取决于是否会被后面覆盖