锁定老帖子 主题:finally 浅谈
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-07-29
public class FinallyTest { public static void main(String args[]) { System.out.println("return: " + new FinallyTest().getString()); } public String getString() { String returnString = null; try { returnString = "this string will be return."; return returnString; }finally { System.out.println("execute finally..."); System.out.println("before clean returnString's value: " + returnString); returnString = null; System.out.println("after clean returnString's value: " + returnString); System.out.println("execute finally end."); } } } 测试结题: execute finally... before clean returnString's value: this string will be return. after clean returnString's value: null execute finally end. return: this string will be return. 如果返回前执行,那么返回的字符串应该为空。但从结果来看,似乎出人的意料之外。 考虑原因:返回前将返回的结果拷贝了。 于是做了以下修改: public class FinallyTest { public static void main(String args[]) { System.out.println("return: " + new FinallyTest().getMessage().message); } public Message getMessage() { Message returnMessage = new Message(); try { returnMessage.message = "message"; return returnMessage; }finally { System.out.println("execute finally..."); System.out.println("before clean returnString's value: " + returnMessage.message); returnMessage.message = null; System.out.println("after clean returnString's value: " + returnMessage.message); System.out.println("execute finally end."); } } } class Message { public String message = "message"; } 结果: execute finally... before clean returnString's value: message after clean returnString's value: null execute finally end. return: null 从结果来看,只调用了对象的引用,而对象没有被拷贝。 看来,如所下用 finally 统一处理一般数据类型还是免谈了。 public class FinallyTest { public static void main(String args[]) { System.out.println("return: " + new FinallyTest().getInt()); } public int getInt() { int returnInt = 0; try { returnInt = 1; throw new RuntimeException("..."); }catch(Exception e) { returnInt = 2; return returnInt; }finally { System.out.println("execute finally..."); System.out.println("before switch returnInt's value: " + returnInt); switch(returnInt) { case 1: returnInt = 0; break; case 2: returnInt = 3; break; default: returnInt = 4; } System.out.println("after switch returnInt's value: " + returnInt); System.out.println("execute finally end."); } } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-07-29
不明白为什么要出现对象拷贝
而你想要的结果又是什么样子的? |
|
返回顶楼 | |
发表时间:2010-07-29
public class FinallyTest { public static void main(String args[]) { System.out.println("return: " + new FinallyTest().getString()); } public String getString() { String returnString = null; try { returnString = "this string will be return."; return returnString; }finally { System.out.println("execute finally..."); System.out.println("before clean returnString's value: " + returnString); returnString = null; System.out.println("after clean returnString's value: " + returnString); System.out.println("execute finally end."); } } } 以上一段相当于以下,所以根本没有错。就喜欢简单问题复杂化。 public class FinallyTest { public static void main(String args[]) { System.out.println("return: " + new FinallyTest().getString()); } public String getString() { String returnString = null; try { returnString = "this string will be return."; System.out.println("execute finally..."); System.out.println("before clean returnString's value: " + returnString); returnString = null; System.out.println("after clean returnString's value: " + returnString); System.out.println("execute finally end."); return returnString; }finally { } } } |
|
返回顶楼 | |
发表时间:2010-07-29
“返回前将返回的结果拷贝了。” 应该是拷贝了对象的引用
基本数据类型和String的值是不能改变的,基本数据类型和String的值改变后,变量的引用也改变了,但return 返回前的拷贝的引用却没有变,所以 new FinallyTest().getString() 的值是“this string will be return.” 改变Message.message的值对象的引用是没有变化的,所以 new FinallyTest().getMessage().message 返回 null |
|
返回顶楼 | |
发表时间:2010-07-29
最后修改:2010-07-29
楼主回答有些许问题。。
对象绝对没有 Copy. 或者说是克隆。你要用Java,就要知道Java的设计者如何设计java .这问题就解决 那为什么呢, return obj; 只是 将返回引用(returnPointer),指向了obj 这个引用 指向的对象, 并没有Copy, 虽然,你在 finally 里面,把obj=null; 那只是, obj 这个引用,指向发生了变化,没有影响返回引用(returnPointer) |
|
返回顶楼 | |
发表时间:2010-07-29
最后修改:2010-07-29
可能还是有人看不懂。。
我来说明下。 public class A{ public String m(){ //xxxx代码 return obj;// return obj ,只是把obj 指向的地址,交给 returnAddress; finally 里面的代码,在这步后运行 } } //Java会以下面的方式来执行,翻译成下面的 public class A{ public String m(){ //xxxx代码 Object returnPointer=obj;// 你看不见的隐式 引用,Java每个方法,都返回一个 返回 return (String)returnPointer; } } 其实,你的代码相当于 1. public class FinallyTest 2. { 3. public static void main(String args[]) 4. { 5. System.out.println("return: " + new FinallyTest().getString()); 6. } 7. 8. public String getString() 9. { 10. String returnString = null; 11. try 12. { 13. returnString = "this string will be return."; ############ String returnPointer=returnString;// 隐式的,看不到。。。。。################### 14. return returnPointer; //############################## 15. }finally 16. { 17. System.out.println("execute finally..."); 18. System.out.println("before clean returnString's value: " + returnString); 19. returnString = null; 20. System.out.println("after clean returnString's value: " + returnString); 21. System.out.println("execute finally end."); 22. } 23. } 24. } 这下,这个方法的返回值,当然不为空了。。。。。。。。。 |
|
返回顶楼 | |
发表时间:2010-07-29
容易误导人,投了隐藏贴。
|
|
返回顶楼 | |
发表时间:2010-07-29
public java.lang.String getString(); Code: 0: aconst_null 1: astore_1 2: ldc #48; //String this string will be return. 4: astore_1 5: aload_1 6: astore_3 7: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream; 10: ldc #50; //String sss 12: invokevirtual #41; //Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 15: aconst_null 16: astore_1 17: aload_3 18: areturn 19: astore_2 20: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream; 23: ldc #50; //String sss 25: invokevirtual #41; //Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 28: aconst_null 29: astore_1 30: aload_2 31: athrow
public String getString() { String returnString = null; try { returnString = "this string will be return."; return returnString; } finally { System.out.println("sss"); returnString = null; } }
其实是先返回再执行finally
|
|
返回顶楼 | |
发表时间:2010-07-29
yangguo 写道 public class FinallyTest { public static void main(String args[]) { System.out.println("return: " + new FinallyTest().getString()); } public String getString() { String returnString = null; try { returnString = "this string will be return."; return returnString; }finally { System.out.println("execute finally..."); System.out.println("before clean returnString's value: " + returnString); returnString = null; System.out.println("after clean returnString's value: " + returnString); System.out.println("execute finally end."); } } } 以上一段相当于以下,所以根本没有错。就喜欢简单问题复杂化。 public class FinallyTest { public static void main(String args[]) { System.out.println("return: " + new FinallyTest().getString()); } public String getString() { String returnString = null; try { returnString = "this string will be return."; System.out.println("execute finally..."); System.out.println("before clean returnString's value: " + returnString); returnString = null; System.out.println("after clean returnString's value: " + returnString); System.out.println("execute finally end."); return returnString; }finally { } } } 如果是这样的话 也不能解释得到的结果吧 |
|
返回顶楼 | |
发表时间:2010-07-29
楼主你试下这个程序看看,看看能不能猜到运行结果。
public class Danteng{ public static void main(String[] args){ doSomething(); } static void doSomething(){ try{ System.out.println("try..."); doSomething(); }finally{ System.out.println("finally"); doSomething(); } } } |
|
返回顶楼 | |