总结:
1.不管有无异常,finally中的代码都会执行
2.无论在try中返回,还是在catch中返回,都要先执行finally
3.如果finally中有return语句执行,那么try和catch中的return语句都会失效。程序在try或catch中return后会进入finally并最终会使用finally中的return进行返回
4.返回的结果在try或catch中return时,便已经准备好了,并存放到一个临时变量中,执行完finally后再从中取出,所以在finally中对原变量的修改不会影响返回值,基本数据类型和引用类型都满足
5.finally中不能改变返回的引用变量,因为有临时变量存在,改变无效。但是可以改变返回的引用变量所指的对象的内容(因为持有对象的引用,所以可以访问并修改)
package Blue2Te.Test;
/**
* Created by Blue2Te on 16/11/13.
*/
public class TryFinallyTest {
/**
* Test测试
* 0无异常测试
* 1有异常测试
* 正常返回0
* try中返回为1
* catch中返回为2
* finally中返回为3
*
* specialTest测试
*/
public static void main(String args[]){
//Test
/**
* Test1测试 try{}catch(){}finally{} return;
*/
System.out.println(Test1(0));
System.out.println(Test1(1));
/**
* Test2 0测试 try{return} catch(){} finally{} return;
* Test2 1测试 try{} catch(){return} finally{} return;
*/
System.out.println(Test2(0));
System.out.println(Test2(1));
/**
* Test3 0测试 try{return} catch(){} finally{return} ;
* Test3 1测试 try{} catch(){return} finally{return} ;
*/
System.out.println(Test3(0));
System.out.println(Test3(1));
//specialTest
System.out.println("specialTes1 return: "+specialTest1());
System.out.println("specialTest1AddForCatch return: "+specialTest1AddForCatch());
MyPoint raw=new MyPoint();
MyPoint ret = specialTest2(raw);
System.out.println("specialTest2 comparation raw==ret: "+(raw == ret));
raw=new MyPoint();
ret = specialTest2AddForCatch(raw);
System.out.println("specialTest2AddForCatch comparation raw==ret: "+(raw == ret));
raw = new MyPoint();
System.out.println("Before specialTest3");
System.out.println(raw);
specialTest3(raw);
System.out.println("After specialTest3");
System.out.println(raw);
raw = new MyPoint();
System.out.println("Before specialTest3AddForCatch");
System.out.println(raw);
specialTest3AddForCatch(raw);
System.out.println("After specialTest3AddForCatch");
System.out.println(raw);
}
//Test
/*
不管有没有出现异常,finally块中代码都会执行
Test1 iCase0 try
Test1 iCase0 finally
0
Test1 iCase1 try
Test1 iCase1 catch
Test1 iCase1 finally
0
*/
public static int Test1(int iCase){
if(iCase==0){
try {
System.out.println("Test1 iCase"+iCase+" try");
}catch (Exception e){
System.out.println("Test1 iCase"+iCase+" catch");
}finally {
System.out.println("Test1 iCase"+iCase+" finally");
}
}else{
try {
System.out.println("Test1 iCase"+iCase+" try");
throw new Exception("For Test1 Exception");
}catch (Exception e){
System.out.println("Test1 iCase"+iCase+" catch");
}finally {
System.out.println("Test1 iCase"+iCase+" finally");
}
}
return 0;
}
/*
无论在try中返回,还是在catch中返回,都要先执行finally
Test2 iCase0 try
Test2 iCase0 finally
1
Test2 iCase1 try
Test2 iCase1 catch
Test2 iCase1 finally
2
*/
public static int Test2(int iCase){
if(iCase==0){
try {
System.out.println("Test2 iCase"+iCase+" try");
return iCase+1;
}catch (Exception e){
System.out.println("Test2 iCase"+iCase+" catch");
}finally {
System.out.println("Test2 iCase"+iCase+" finally");
}
}else{
try {
System.out.println("Test2 iCase"+iCase+" try");
throw new Exception("For Test2 Exception");
}catch (Exception e){
System.out.println("Test2 iCase"+iCase+" catch");
return iCase+1;
}finally {
System.out.println("Test2 iCase"+iCase+" finally");
}
}
return 0;
}
/*
如果finally中有return语句执行,那么try和catch中的return语句都会失效
程序在try或catch中return后会进入finally并最终会使用finally中的return进行返回
Test3 iCase0 try
Test3 iCase0 finally
3
Test3 iCase1 try
Test3 iCase1 catch
Test3 iCase1 finally
3
*/
public static int Test3(int iCase){
if(iCase==0){
try {
System.out.println("Test3 iCase"+iCase+" try");
return iCase+1;
}catch (Exception e){
System.out.println("Test3 iCase"+iCase+" catch");
}finally {
System.out.println("Test3 iCase"+iCase+" finally");
return iCase+3;
}
}else{
try {
System.out.println("Test3 iCase"+iCase+" try");
throw new Exception("For Test3 Exception");
}catch (Exception e){
System.out.println("Test3 iCase"+iCase+" catch");
return iCase+1;
}finally {
System.out.println("Test3 iCase"+iCase+" finally");
return iCase+2;
}
}
}
//specialTest
/*
基本数据类型的测试
try var: 1
finally var: 2
specialTes1 return: 1
try var: 1
catch var: 2
finally var: 3
specialTest1AddForCatch return: 2
从结果可以看出,finally中对var的修改并没有影响到返回值
返回的结果在try或catch中return时,便已经准备好了,并存放到一个临时变量中,执行完finally后再从中取出
所以在finally中对原变量的修改不会影响返回值
*/
public static int specialTest1(){
int var = 0;
try{
++var; //var=1;
System.out.println("try var: "+var);
return var;
}catch (Exception e){
e.printStackTrace();
}finally {
++var; //var=2;
System.out.println("finally var: "+var);
}
return -1;
}
public static int specialTest1AddForCatch(){
int var = 0;
try{
++var; //var=1;
System.out.println("try var: "+var);
throw new Exception();
}catch (Exception e){
++var; //var=2;
System.out.println("catch var: "+var);
return var;
}finally {
++var; //var=3;
System.out.println("finally var: "+var);
}
}
/*
引用类型的测试
*/
static class MyPoint{
int x;
int y;
public MyPoint(){
x=0;
y=0;
}
@Override
public String toString() {
return "x: "+x+" y: "+y;
}
}
/*
是否为同一个对象的测试
finally raw==newMyPoint:false
specialTest2 comparation raw==ret: true
finally raw==newMyPoint:false
specialTest2AddForCatch comparation raw==ret: true
结果说明引用变量的返回与基本数据类型一致,在return时会先将引用变量保存到一个临时变量中,再转去finally中执行,
finally中对引用变量的修改不影响前面的临时变量,finally结束后会将前面的临时变量返回。
*/
public static MyPoint specialTest2(MyPoint raw){
MyPoint newMyPoint = new MyPoint();
try{
return raw;
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("finally raw==newMyPoint:"+(raw==newMyPoint));
raw = newMyPoint;
}
return null;
}
public static MyPoint specialTest2AddForCatch(MyPoint raw){
MyPoint newMyPoint = new MyPoint();
try{
throw new Exception();
}catch (Exception e){
return raw;
}finally {
System.out.println("finally raw==newMyPoint:"+(raw==newMyPoint));
raw = newMyPoint;
}
}
/*
finally中不能改变返回的引用变量地址信息(specialTest2测试),因为有临时变量存在,改变无效
但是可以改变返回的引用变量所指的对象的内容(因为持有对象的引用,所以可以访问并修改)
Before specialTest3
x: 0 y: 0
After specialTest3
x: -1 y: -1
Before specialTest3AddForCatch
x: 0 y: 0
After specialTest3AddForCatch
x: -2 y: -2
*/
public static MyPoint specialTest3(MyPoint raw){
try{
return raw;
}catch (Exception e){
e.printStackTrace();
}finally {
raw.x=-1;
raw.y=-1;
}
return null;
}
public static MyPoint specialTest3AddForCatch(MyPoint raw){
try{
throw new Exception();
}catch (Exception e){
return raw;
}finally {
raw.x=-2;
raw.y=-2;
}
}
}