package com.exception.test;public class test {
public static void main(String[] args)
{
TT ttt=t();
System.out.println(ttt);
System.out.println("a:"+ttt.a+" b:"+ttt.b);
}
public static class TT
{
public int a;
public int b;
public TT(int a,int b)
{
this.a=a;
this.b=b;
}
}
public static TT t()
{
TT ttt=new test.TT(1,2);
String tt=new String("try");
try{
System.out.println(ttt);
return ttt;
}catch(Exception e)
{
System.out.println("catch");
}finally{
ttt=new test.TT(11,22);
ttt.b=222;
System.out.println(ttt);
System.out.println("do finally");
}
return ttt;
}
}为什么在finally里对ttt的修改无效呢?
如果单纯的修改ttt的成员又可以呢?
能具体解析下fianlly代码块里是怎么执行和原理吗?java
直接使用这句ttt.b=222;却可以改变返回值呢?
public static void main(String[] args) {
TT ttt = t();
System.out.println(ttt);//3
System.out.println("a:" + ttt.a + " b:" + ttt.b);
} public static class TT {
public int a;
public int b; public TT(int a, int b) {
this.a = a;
this.b = b;
}
} public static TT t() {
TT ttt = new test.TT(1, 2);
try {
System.out.println(ttt);//1
return ttt;
} catch (Exception e) {
System.out.println("catch");
} finally {
System.out.println("do finally");
ttt = new test.TT(11, 22);
ttt.b = 222;
System.out.println(ttt);//2
}
return ttt;
}
}
com.withiter.csdn.test.test$TT@58d9660d //1
do finally
com.withiter.csdn.test.test$TT@28bb0d0d //2
com.withiter.csdn.test.test$TT@58d9660d //3
a:1 b:2可以看到2和3是不同的对象,所以你修改的对象2对3打印没有影响!
直接使用这句ttt.b=222;却可以改变返回值呢?
在 新建 第一个的时候
TT ttt=new test.TT(1,2);
ttt 指向的是 new test.TT(1,2)
如果你在finally 运行
ttt = new test.TT(11, 22);
相当于你重新定义了 ttt的指向 现在ttt指向 new test.TT(11, 22)
所有之后你修改ttt.b = 222; 就等于 吧 new test.TT(11, 22) 的b 改成222.而如果你没有重新定义的话。
ttt还是指向new test.TT(1,2)。
所以你修改 ttt.b 就想相当于修改原地址的 b。
所以出来值会变。
还有如果没有在finally里new一个新的对象,而直接改第一个对象的值,那返回值改变了,不是很懂其中的原理。
直接使用这句ttt.b=222;却可以改变返回值呢?
在 新建 第一个的时候
TT ttt=new test.TT(1,2);
ttt 指向的是 new test.TT(1,2)
如果你在finally 运行
ttt = new test.TT(11, 22);
相当于你重新定义了 ttt的指向 现在ttt指向 new test.TT(11, 22)
所有之后你修改ttt.b = 222; 就等于 吧 new test.TT(11, 22) 的b 改成222.而如果你没有重新定义的话。
ttt还是指向new test.TT(1,2)。
所以你修改 ttt.b 就想相当于修改原地址的 b。
所以出来值会变。
那是不是就是保存第一个对象的地址在方法栈那里了?
但如果在try{} 块里return了, JVM必须保持 return的引用,并等待finally{}运行结束后返回这个引用。
所以finally{}的新建的引用,或重新给引用赋值不会改变返回结果的。
但因为引用实际上是对象的地址,所以在finally里对应用指向的对象属性进行修改,是能体现在返回结果里的。
不知道这么说你能明白么。
说白了就是 26行的return ttt; 运行后JVM 就已经确定了这个方法的返回值,为ttt指向的地址:new test.TT(1, 2)
所以后续再finally{}里即使你试着给ttt重新分配地址,返回的还是之前26的地址。 但由于finally{} 会在返回前执行,所以当你在finally{}中修改26行的引用指向的对象属性值时,这个修改会在返回值中体现出来。
理解上诉 你需要了解 按值传递和引用传递的意义。