关于trycatchfinal返回值问题

时间:2022-01-22 18:23:22

关于try...catch...finally中return的疑惑

关于try...catch...finally里面的return一直是面试的一个热门考点。无非就分以下几个情况:

1、当有finally语句并且try中有return,在执行到return(还未执行)的时候,会先执行finally里面的内容,然后再执行行try中的return。

关于trycatchfinal返回值问题
package com.and.java.demo;

public class 测试 {
public static void main(String[] args) {
System.out.println(
new 测试().test());
}

public String test() {
try {
System.out.println(
"try{...}");
return "try";
}
catch (Exception e) {
System.out.println(
"catch{...}");
return "catch";
}
finally {
System.out.println(
"finally{...}");
}
}
}
关于trycatchfinal返回值问题

输出:

try{...}
finally{...}
try

2、在1的基础上,如果finally里面也有return语句,则try代码块中的return被屏蔽(不执行),即在try中遇到return的时候,会先执行finally里面的内容(包括finally里面的return语句)。

关于trycatchfinal返回值问题
package com.and.java.demo;

public class 测试 {
public static void main(String[] args) {
System.out.println(
new 测试().test());
}

public String test() {
try {
System.out.println(
"try{...}");
return "try";
}
catch (Exception e) {
System.out.println(
"catch{...}");
return "catch";
}
finally {
System.out.println(
"finally{...}");
return "finally";
}
}
}
关于trycatchfinal返回值问题

输出:

try{...}
finally{...}
finally

遇到的问题:

这两种情况想必大家已经掌握。但是还有一种情况,也是我不能理解的地方。一般情况下,在finally里面作一些数据的关闭操作(比如文件,输入/输出流,数据库的关闭),试想一下,要是我们在finally里面对要返回的值进行修改,那会反应到最终的结果上去吗?(因为从上面的讲解可以知道,当try里面有return的时候,它不会立刻执行,会先执行finally里面的内容,然后再执行return)。

关于trycatchfinal返回值问题
package com.and.java.demo;

public class 测试 {
public static void main(String[] args) {
System.out.println(
new 测试().test());
}

public String test() {
String result
= "";
try {
result
= "try";
return result;
}
catch (Exception e) {
result
= "catch";
return result;
}
finally {
result
= "finally";
}
}
}
关于trycatchfinal返回值问题

试想一下,它会输出"try" 呢还是"finally"呢?

输出:

try

确实只输出try,但是我们在finally里面是改变了result的值呀?
再进一步改进,判断finally里面的赋值语句是否执行

关于trycatchfinal返回值问题
package com.and.java.demo;

public class 测试 {
public static void main(String[] args) {
System.out.println(
new 测试().test());
}

public String test() {
String result
= "";
try {
result
= "try";
return result;
}
catch (Exception e) {
result
= "catch";
return result;
}
finally {
System.out.println(
"t1->"+result);
result
= "finally";
System.out.println(
"t2->"+result);
}
}
}
关于trycatchfinal返回值问题

输出:

t1->try
t2
->finally
try

从输出结果可以看出,finally里面的赋值语句是执行了的,但是在return结果中怎么就没变呢?(目前暂时研究到这个地步,仍没搞明白,还望各位高手指点)

标签:  javatrycatchfinallyreturn

0
0
« 上一篇: 模仿网易新闻客户端(RSS版)(二)
» 下一篇: iOS学习笔记之NSString
posted @  2012-04-17 15:15  And.He 阅读( 5242) 评论( 12编辑  收藏

  
#1楼   2012-04-17 16:55  LAO年糕   
楼主如果记住String是引用类型就很好理解了,例如”try“的地址这里为0x001、“finally”的地址为0x002,在try中return 的result指向的是“try”的地址0x001,所以return的时候返回的也应该是“try“的地址0x001;而在finally中将变量result指向地址修改为0x002 ,但没有使用return返回新的地址,所有在调用入口处得到的指向任然是0x001所以在mai中输出的时候是去0x001取值而不是去0x002取;
这是我的理解,或许存在误解欢迎指点。。。(*^__^*) 嘻嘻
  
#2楼 [ 楼主2012-04-17 21:48  And.He   
欢迎你参与回复,我试过了,与String无关,把String改成int类型也一样,目前我的猜想就是,在try中遇到return的时候,虽然没有立即把当前的值返回出去,但是这个值已经在了,而在finally中,改变了这个值,不影响当前函数的返回值。不知道我表述清楚没有。如果把要返回的值定义在函数外面(全局),可以通过输出查看,最后它的值还是改变了的。只是在try中遇到return的时候,暂时把要返回的值取出来放那儿的,执行完finally后再返回。目前我是这样理解的。欢迎指正
  
#3楼   2012-04-17 22:53  cavlary   
@ And.He
int 也属于值引用的,try,catch,finally是三个不用的作用域,执行try里面的result = "try",然后执行finally里面的result = "finally",其实这个时候try里面的result的值并没有改变,它只是将它的值copy给到了finally,是里面的一个临时变量而已,所以finally里的操作对try里面的值没有改变的,而执行完finally里的操作后,finally里的result就被丢弃了,等着回收
  
#4楼 [ 楼主2012-04-17 23:03  And.He   
你的最后一句我不赞同,再看下面代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public  class  测试 {
     int  i =  0 ;
     public  static  void  main(String[] args) {
         测试 t =  new  测试();
         System.out.println(t.i);
         System.out.println(t.test());
         System.out.println(t.i);
     }
 
     public  int  test() {
         try  {
             i =  1 ;
             return  i;
         catch  (Exception e) {
             i = - 1 ;
             return  i;
         finally  {
             i =  2 ;
         }
     }
}
  
#5楼   2012-04-18 11:53  bevin-H   
是不是和result的作用域有关?我是菜鸟,恳请指正。
  
#6楼   2012-04-18 17:55  houjinxin   
这个问题好复杂,我也想不出合理的解释,这个可能跟底层的一些东西有关吧
  
#7楼   2012-04-18 18:41  houjinxin   
我又研究了一下,发现在finally块中被执行的代码,只有在return的时候才会覆盖try中的结果,换句话说,虽然在finally中改变了result的值,但是并没有被返回,在try,finnaly里都可以返回结果,而finnaly中的返回值会覆盖try中的返回值,既然finnaly中没有返回值,又何来覆盖一说呢!!
  
#8楼   2012-04-18 18:43  houjinxin   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public  class  测试 {
     public  static  void  main(String[] args) {
         System.out.println( new  测试().test());
     }
 
     public  String test() {
         String result =  "" ;
         try  {
             result =  "try" ;
             return  result;
         catch  (Exception e) {
             result =  "catch" ;
             return  result;
         finally  {
             System.out.println( "t1->" +result);
             result =  "finally" ;
             System.out.println( "t2->" +result);
            //在这里加上一行,就会看到返回值变了
          return  result;
         }
     }
}
  
#9楼   2012-04-18 23:03  God Is Coder   

try{
s ="a";
return s;
}catch{
s="b";
return s;
}finally{
s ="c";
}
结构中虚拟机的处理方式是 在try 语句中 会把return的变量引用的对象存入一个局部变量表(虚拟机可见,程序不可见)里面,然后进入finally语句块中,如果finally没有return语句,则处理finally的语句,这个时候finally的变量S和Try中的变量S是同一个变量,所以S的值是改变的。但是finally执行结束之后,return 返回值的时候,会把复制的结果返回

例如下面的代码
public class TryCatchFinally {

@SuppressWarnings("finally")
public Test test() {
Test t = new Test();

try {
t.setS("try");

return t;
} catch (Exception e) {
//result = "catch";
return t;
} finally {
t = new Test();
t.setS("finallyu");
//return result;

}
}

}


class Test{
public String s ="a";
public void setS(String s){
this.s = s;
}
}

其实还是返回的 Test.getS() 结果为 try
  
#10楼 [ 楼主2012-04-19 08:32  And.He   
谢谢大家的热心回答
  
#11楼   2015-05-06 11:22  ChuckLu   
你这个针对哪一个编程语言的?
C#的finally里面,不允许return的
  
#12楼   2017-03-01 17:21  博客管家   
我知道为什么了。博主所说的,try代码块中的return被屏蔽(不执行),是错误的,不会被屏蔽,仍然执行,屏蔽的仅仅是跳转指令。
package com.and.java.demo;

public class 测试 {
public static void main(String[] args) {
System.out.println(new 测试().test());
}

public String test() {
try {
System.out.println("try{...}");
return "try";
} catch (Exception e) {
System.out.println("catch{...}");
return "catch";
} finally {
System.out.println("finally{...}");
return "finally";
}
}
}
分析以上代码,先执行try中的return语句,该语句会将"try"对象的引用保存到CPU的寄存器中,该语句的跳转指令被屏蔽。然后执行finally中的return语句,该语句会将“finally”对象的引用保存到CPU的寄存器中(覆盖了try的),然后执行跳转指令。所以返回的是指向"finally"的指针,但是try中的return的确执行了。
package com.and.java.demo;

public class 测试 {
public static void main(String[] args) {
System.out.println(new 测试().test());
}

public String test() {
String result = "";
try {
result = "try";
return result;
} catch (Exception e) {
result = "catch";
return result;
} finally {
result = "finally";
}
}
}
分析以上代码,先执行try中的return语句(try中的语句总是先执行),该语句会将"try"对象的引用保存到CPU的寄存器中,然后执行finllay语句,该语句会将result局部变量的值重新定位成指向"finally"对象。最后执行跳转指令,因为CPU寄存器中保存的是“try”的引用,所以返回值是"try"的引用。


关闭
 

有return的情况下try catch finally的执行顺序(最有说服力的总结)

标签: 编译器stringclass测试
  134056人阅读  评论(28)  收藏  举报
关于trycatchfinal返回值问题  分类:


结论:
1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
举例:
情况1:try{} catch(){}finally{} return;
            显然程序按顺序执行。
情况2:try{ return; }catch(){} finally{} return;
          程序执行try块中return之前(包括return语句中的表达式运算)代码;
         再执行finally块,最后执行try中return;
         finally块之后的语句return,因为程序在try中已经return所以不再执行。
情况3:try{ } catch(){return;} finally{} return;
         程序先执行try,如果遇到异常执行catch块,
         有异常:则执行catch中return之前(包括return语句中的表达式运算)代码,再执行finally语句中全部代码,
                     最后执行catch块中return. finally之后也就是4处的代码不再执行。
         无异常:执行完try再finally再return.
情况4:try{ return; }catch(){} finally{return;}
          程序执行try块中return之前(包括return语句中的表达式运算)代码;
          再执行finally块,因为finally块中有return所以提前退出。
情况5:try{} catch(){return;}finally{return;}
          程序执行catch块中return之前(包括return语句中的表达式运算)代码;
          再执行finally块,因为finally块中有return所以提前退出。
情况6:try{ return;}catch(){return;} finally{return;}
          程序执行try块中return之前(包括return语句中的表达式运算)代码;
          有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
                       则再执行finally块,因为finally块中有return所以提前退出。
          无异常:则再执行finally块,因为finally块中有return所以提前退出。

最终结论:任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
                  如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
                  编译器把finally中的return实现为一个warning。

 

下面是个测试程序
public class FinallyTest
{
public static void main(String[] args) {

System.out.println(new FinallyTest().test());;
}

static int test()
{
int x = 1;
try
{
x++;
return x;
}
finally
{
++x;
}
}
}
结果是2。
分析:
 在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。
在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,
因此,即使finally中对变量x进行了改变,但是不会影响返回结果。
它应该使用栈保存返回值。

61
 
1
 
 

查看评论
19楼  落叶伤剑2017-04-13 19:06发表 [回复]
关于trycatchfinal返回值问题
如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况,:

1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。

2)如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。
Re:  sinat_382681592017-06-08 20:22发表 [回复]
关于trycatchfinal返回值问题
回复落叶伤剑:谢谢层主!
18楼  飘零雁2016-12-14 10:53发表 [回复]
关于trycatchfinal返回值问题
catch 中有throw 的话,finally不会执行
Re:  口袋本人前天 14:31发表 [回复]
关于trycatchfinal返回值问题
回复飘零雁:会执行的,建议你去实践一下。
17楼  baidu_351455222016-10-17 10:28发表 [回复]
关于trycatchfinal返回值问题
针对第一点,如果catch块中有System.exit(0);那么finally块是不会执行的。try块中同样。
16楼  蜿蜒2016-08-21 10:42发表 [回复]
关于trycatchfinal返回值问题
博主语意矛盾,给人以误解吧,先....之前,再.....,到底谁先谁后?
15楼  huangpingfeng2016-04-22 11:52发表 [回复]
关于trycatchfinal返回值问题
try{ throw e; return;}catch(){throw e} finally{return;}
这种情况,执行了finally的return后,异常也是抛不出来
14楼  huangpingfeng2016-04-22 11:51发表 [回复]
关于trycatchfinal返回值问题
try{ throw e; return;}catch(){throw e} finally{return;}
这种情况,执行了finally的return后,异常也是抛不出来
13楼  丶封刀看海2016-04-10 22:24发表 [回复]
关于trycatchfinal返回值问题
学习了
12楼  thewindkee2016-03-07 21:57发表 [回复]
关于trycatchfinal返回值问题
因为使用栈保存返回值,即使finally中执行i++,但是影响不到之前保存下来的具体的值。 所以return影响不了基本型的值。
而修改list ,map,自定义类等引用类型时,虽然进入finally之前保存了引用的地址,所以在finally中引用地址指向的内容改变了, 影响了返回值。
11楼  wangqiang54172016-03-06 01:33发表 [回复]
关于trycatchfinal返回值问题
从SEH角度分析更容易理解
10楼  飞碟说2016-01-26 09:52发表 [回复]
关于trycatchfinal返回值问题
逻辑清晰,浅显易懂,亲测之后果然如此,谢谢楼主。
9楼  -琥珀川-2015-08-26 14:36发表 [回复]
关于trycatchfinal返回值问题
:try{ return;}catch(){return;} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
则再执行finally块,因为finally块中有return所以提前退出。
无异常:则再执行finally块,因为finally块中有return所以提前退出。

finally中有return会吃掉异常的
Re:  wxb7745678762016-03-09 08:37发表 [回复]
关于trycatchfinal返回值问题
回复最后一句话确实经典,一语惊醒。:
Re:  青蛙的世界2016-02-14 20:10发表 [回复]
关于trycatchfinal返回值问题
回复-琥珀川-:大兄弟啊有个问题一直没搞懂你这最后一句话救了我的命啊
8楼  风雨常乐2015-05-08 09:39发表 [回复]
关于trycatchfinal返回值问题
谢谢楼主
7楼  zspmaomao2014-11-25 10:05发表 [回复]
关于trycatchfinal返回值问题
1.影响返回结果的前提是在 非 finally 语句块中有 return 且非基本类型
2.不影响返回结果 的前提是 非 finally 块中有return 且为基本类型

这也解释了,为什么Date类型是被修改的,究其本质 基本类型在栈中存储,返回的是真实的值,而引用类型返回的是其浅拷贝堆地址.所以才会改变~
6楼  浪羽清风2014-11-06 18:01发表 [回复]
关于trycatchfinal返回值问题
引用“wangq2110”的评论:测试demo
[code=csharp]
static void Main(string[] ar...

基本数据类型是不能修改的,其他的可以修改,包括date
Re:  wangq21102014-11-14 13:32发表 [回复]
关于trycatchfinal返回值问题
回复浪羽清风:听不懂你在说啥!惜字如金啊!我只希望有人给出原因,而不是结论。
5楼  wangq21102014-10-24 16:02发表 [回复]
关于trycatchfinal返回值问题
测试demo
[csharp]  view plain  copy
  1. static void Main(string[] args)  
  2.        {  
  3.          /*测试test1*/   
  4.            List<string>relist=test1();  
  5.            foreach (var item in relist)  
  6.            {  
  7.                Console.WriteLine(item);  
  8.            }  
  9.            Console.ReadLine();  
  10.        }  
  11.        private static List<string> test1()  
  12.        {  
  13.            List<string> strlist = new List<string>();  
  14.            strlist.Add("zs");  
  15.            strlist.Add("ls");  
  16.            strlist.Add("ww");  
  17.            strlist.Add("mz");  
  18.            try  
  19.            {  
  20.                strlist.Add("wq");  
  21.                return strlist;  
  22.            }  
  23.            finally  
  24.            {  
  25.                strlist.Add("yyy");  
  26.            }  
  27.        }  

测试输出结果:
zs
ls
ww
mz
wq
yyy
4楼  wangq21102014-10-24 15:57发表 [回复]
关于trycatchfinal返回值问题
楼主,求真相。求解释。共同学习。
3楼  wangq21102014-10-24 15:55发表 [回复]
关于trycatchfinal返回值问题
引用“pairsfish”的评论:楼主之写的有些片面,得出的结论是不正确的。finally修改的基本类型是不影响返回结果的。
修改li...

我也测试了,是你说的这样,是不是和return,finally的执行顺序无关,是不是值类型和引用类型搞的鬼。郁闷!
2楼  pairsfish2014-09-19 17:16发表 [回复]
关于trycatchfinal返回值问题
楼主之写的有些片面,得出的结论是不正确的。finally修改的基本类型是不影响返回结果的。
修改list ,map,自定义类等引用类型时,是影响返回结果 的。
但是date类型经过测试是不影响的。有点奇怪。
Re:  Marksinoberg2017-03-08 21:07发表 [回复]
关于trycatchfinal返回值问题
回复pairsfish:date类型底层貌似是对long类型的数据的封装,也就是说JVM可能在编译的时候指定了一个常量值保存了起来,所以在finally块中修改的其实不是date底层所指向的那个副本,而是对类似于基本数据类型的修改,所以返回的结果仍然是一开始编译好的时候指定的副本。也就是没变的原因。

而其他的对象(引用类型)则是被finally块中的代码改变了所引用变量的真实数据,所以发生了改变。

也就是说,严格来讲,Date类型是个伪对象类型。

以上均为个人观点,如果有误,还望指出,大家一起研究。 :)
Re:  lingzhm2015-08-19 16:29发表 [回复]
关于trycatchfinal返回值问题
回复pairsfish:我试过了,果然如你所说。。。。真奇怪了。。。
Re:  VirgoSoy2015-09-12 14:52发表 [回复]
关于trycatchfinal返回值问题
回复lingzhm::本人新手,以下是自己的观点。。感觉与参数传值或传址类似。前几天才知道java全部都是传值的,即使是对象也是传递其地址的副本。return的若是对象,则先把对象的副本保存起来,也就是说保存的是指向对象的地址。若对原来的对象进行修改。对象的地址仍然不变,return的副本仍然是指向这个对象,所用finally中对对象的修改仍然有作用。而基本数据类型保存的是原原本本的数据,return保存副本后,在finally中修改都是修改原来的数据。副本中的数据还是不变,所以finally中修改对return无影响。。
Re:  Marksinoberg2017-03-08 20:57发表 [回复]
关于trycatchfinal返回值问题
回复VirgoSoy:我觉得你总结的很好,很有道理。Java关于方法返回值应该就是对这个引用(或者基本数据)而操作的。
1楼  Optimistic_2014-09-16 08:35发表 [回复]
关于trycatchfinal返回值问题
学习了……
发表评论
  • 用 户 名:
  • zhoulovelian
  • 评论内容:
  • 关于trycatchfinal返回值问题
      
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    关于trycatchfinal返回值问题 
    kavensu
     
    • 访问:620521次
    • 积分:4873
    • 等级: 关于trycatchfinal返回值问题 
    • 排名:第5919名
    • 原创:39篇
    • 转载:108篇
    • 译文:4篇
    • 评论:103条
    文章存档
    最新评论

关闭
 

有return的情况下try catch finally的执行顺序(最有说服力的总结)

标签: 编译器stringclass测试
  134056人阅读  评论(28)  收藏  举报
关于trycatchfinal返回值问题  分类:


结论:
1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
举例:
情况1:try{} catch(){}finally{} return;
            显然程序按顺序执行。
情况2:try{ return; }catch(){} finally{} return;
          程序执行try块中return之前(包括return语句中的表达式运算)代码;
         再执行finally块,最后执行try中return;
         finally块之后的语句return,因为程序在try中已经return所以不再执行。
情况3:try{ } catch(){return;} finally{} return;
         程序先执行try,如果遇到异常执行catch块,
         有异常:则执行catch中return之前(包括return语句中的表达式运算)代码,再执行finally语句中全部代码,
                     最后执行catch块中return. finally之后也就是4处的代码不再执行。
         无异常:执行完try再finally再return.
情况4:try{ return; }catch(){} finally{return;}
          程序执行try块中return之前(包括return语句中的表达式运算)代码;
          再执行finally块,因为finally块中有return所以提前退出。
情况5:try{} catch(){return;}finally{return;}
          程序执行catch块中return之前(包括return语句中的表达式运算)代码;
          再执行finally块,因为finally块中有return所以提前退出。
情况6:try{ return;}catch(){return;} finally{return;}
          程序执行try块中return之前(包括return语句中的表达式运算)代码;
          有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
                       则再执行finally块,因为finally块中有return所以提前退出。
          无异常:则再执行finally块,因为finally块中有return所以提前退出。

最终结论:任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
                  如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
                  编译器把finally中的return实现为一个warning。

 

下面是个测试程序public class FinallyTest  
{
public static void main(String[] args) {

System.out.println(new FinallyTest().test());;
}

static int test()
{
int x = 1;
try
{
x++;
return x;
}
finally
{
++x;
}
}
}
结果是2。
分析:
 在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,因此,即使finally中对变量x进行了改变,但是不会影响返回结果。它应该使用栈保存返回值。

61
 
1
 
 

查看评论
19楼  落叶伤剑2017-04-13 19:06发表 [回复]
关于trycatchfinal返回值问题
如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况,:

1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。

2)如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。
Re:  sinat_382681592017-06-08 20:22发表 [回复]
关于trycatchfinal返回值问题
回复落叶伤剑:谢谢层主!
18楼  飘零雁2016-12-14 10:53发表 [回复]
关于trycatchfinal返回值问题
catch 中有throw 的话,finally不会执行
Re:  口袋本人前天 14:31发表 [回复]
关于trycatchfinal返回值问题
回复飘零雁:会执行的,建议你去实践一下。
17楼  baidu_351455222016-10-17 10:28发表 [回复]
关于trycatchfinal返回值问题
针对第一点,如果catch块中有System.exit(0);那么finally块是不会执行的。try块中同样。
16楼  蜿蜒2016-08-21 10:42发表 [回复]
关于trycatchfinal返回值问题
博主语意矛盾,给人以误解吧,先....之前,再.....,到底谁先谁后?
15楼  huangpingfeng2016-04-22 11:52发表 [回复]
关于trycatchfinal返回值问题
try{ throw e; return;}catch(){throw e} finally{return;}
这种情况,执行了finally的return后,异常也是抛不出来
14楼  huangpingfeng2016-04-22 11:51发表 [回复]
关于trycatchfinal返回值问题
try{ throw e; return;}catch(){throw e} finally{return;}
这种情况,执行了finally的return后,异常也是抛不出来
13楼  丶封刀看海2016-04-10 22:24发表 [回复]
关于trycatchfinal返回值问题
学习了
12楼  thewindkee2016-03-07 21:57发表 [回复]
关于trycatchfinal返回值问题
因为使用栈保存返回值,即使finally中执行i++,但是影响不到之前保存下来的具体的值。 所以return影响不了基本型的值。
而修改list ,map,自定义类等引用类型时,虽然进入finally之前保存了引用的地址,所以在finally中引用地址指向的内容改变了, 影响了返回值。
11楼  wangqiang54172016-03-06 01:33发表 [回复]
关于trycatchfinal返回值问题
从SEH角度分析更容易理解
10楼  飞碟说2016-01-26 09:52发表 [回复]
关于trycatchfinal返回值问题
逻辑清晰,浅显易懂,亲测之后果然如此,谢谢楼主。
9楼  -琥珀川-2015-08-26 14:36发表 [回复]
关于trycatchfinal返回值问题
:try{ return;}catch(){return;} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
则再执行finally块,因为finally块中有return所以提前退出。
无异常:则再执行finally块,因为finally块中有return所以提前退出。

finally中有return会吃掉异常的
Re:  wxb7745678762016-03-09 08:37发表 [回复]
关于trycatchfinal返回值问题
回复最后一句话确实经典,一语惊醒。:
Re:  青蛙的世界2016-02-14 20:10发表 [回复]
关于trycatchfinal返回值问题
回复-琥珀川-:大兄弟啊有个问题一直没搞懂你这最后一句话救了我的命啊
8楼  风雨常乐2015-05-08 09:39发表 [回复]
关于trycatchfinal返回值问题
谢谢楼主
7楼  zspmaomao2014-11-25 10:05发表 [回复]
关于trycatchfinal返回值问题
1.影响返回结果的前提是在 非 finally 语句块中有 return 且非基本类型
2.不影响返回结果 的前提是 非 finally 块中有return 且为基本类型

这也解释了,为什么Date类型是被修改的,究其本质 基本类型在栈中存储,返回的是真实的值,而引用类型返回的是其浅拷贝堆地址.所以才会改变~
6楼  浪羽清风2014-11-06 18:01发表 [回复]
关于trycatchfinal返回值问题
引用“wangq2110”的评论:测试demo
[code=csharp]
static void Main(string[] ar...

基本数据类型是不能修改的,其他的可以修改,包括date
Re:  wangq21102014-11-14 13:32发表 [回复]
关于trycatchfinal返回值问题
回复浪羽清风:听不懂你在说啥!惜字如金啊!我只希望有人给出原因,而不是结论。
5楼  wangq21102014-10-24 16:02发表 [回复]
关于trycatchfinal返回值问题
测试demo
[csharp]  view plain  copy
  1. static void Main(string[] args)  
  2.        {  
  3.          /*测试test1*/   
  4.            List<string>relist=test1();  
  5.            foreach (var item in relist)  
  6.            {  
  7.                Console.WriteLine(item);  
  8.            }  
  9.            Console.ReadLine();  
  10.        }  
  11.        private static List<string> test1()  
  12.        {  
  13.            List<string> strlist = new List<string>();  
  14.            strlist.Add("zs");  
  15.            strlist.Add("ls");  
  16.            strlist.Add("ww");  
  17.            strlist.Add("mz");  
  18.            try  
  19.            {  
  20.                strlist.Add("wq");  
  21.                return strlist;  
  22.            }  
  23.            finally  
  24.            {  
  25.                strlist.Add("yyy");  
  26.            }  
  27.        }  

测试输出结果:
zs
ls
ww
mz
wq
yyy
4楼  wangq21102014-10-24 15:57发表 [回复]
关于trycatchfinal返回值问题
楼主,求真相。求解释。共同学习。
3楼  wangq21102014-10-24 15:55发表 [回复]
关于trycatchfinal返回值问题
引用“pairsfish”的评论:楼主之写的有些片面,得出的结论是不正确的。finally修改的基本类型是不影响返回结果的。
修改li...

我也测试了,是你说的这样,是不是和return,finally的执行顺序无关,是不是值类型和引用类型搞的鬼。郁闷!
2楼  pairsfish2014-09-19 17:16发表 [回复]
关于trycatchfinal返回值问题
楼主之写的有些片面,得出的结论是不正确的。finally修改的基本类型是不影响返回结果的。
修改list ,map,自定义类等引用类型时,是影响返回结果 的。
但是date类型经过测试是不影响的。有点奇怪。
Re:  Marksinoberg2017-03-08 21:07发表 [回复]
关于trycatchfinal返回值问题
回复pairsfish:date类型底层貌似是对long类型的数据的封装,也就是说JVM可能在编译的时候指定了一个常量值保存了起来,所以在finally块中修改的其实不是date底层所指向的那个副本,而是对类似于基本数据类型的修改,所以返回的结果仍然是一开始编译好的时候指定的副本。也就是没变的原因。

而其他的对象(引用类型)则是被finally块中的代码改变了所引用变量的真实数据,所以发生了改变。

也就是说,严格来讲,Date类型是个伪对象类型。

以上均为个人观点,如果有误,还望指出,大家一起研究。 :)
Re:  lingzhm2015-08-19 16:29发表 [回复]
关于trycatchfinal返回值问题
回复pairsfish:我试过了,果然如你所说。。。。真奇怪了。。。
Re:  VirgoSoy2015-09-12 14:52发表 [回复]
关于trycatchfinal返回值问题
回复lingzhm::本人新手,以下是自己的观点。。感觉与参数传值或传址类似。前几天才知道java全部都是传值的,即使是对象也是传递其地址的副本。return的若是对象,则先把对象的副本保存起来,也就是说保存的是指向对象的地址。若对原来的对象进行修改。对象的地址仍然不变,return的副本仍然是指向这个对象,所用finally中对对象的修改仍然有作用。而基本数据类型保存的是原原本本的数据,return保存副本后,在finally中修改都是修改原来的数据。副本中的数据还是不变,所以finally中修改对return无影响。。
Re:  Marksinoberg2017-03-08 20:57发表 [回复]
关于trycatchfinal返回值问题
回复VirgoSoy:我觉得你总结的很好,很有道理。Java关于方法返回值应该就是对这个引用(或者基本数据)而操作的。
1楼  Optimistic_2014-09-16 08:35发表 [回复]
关于trycatchfinal返回值问题
学习了……
发表评论
  • 用 户 名:
  • zhoulovelian
  • 评论内容:
  • 关于trycatchfinal返回值问题
      
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    关于trycatchfinal返回值问题 
    kavensu
     
    • 访问:620521次
    • 积分:4873
    • 等级: 关于trycatchfinal返回值问题 
    • 排名:第5919名
    • 原创:39篇
    • 转载:108篇
    • 译文:4篇
    • 评论:103条
    文章存档
    最新评论