最近发现很多人在这里存在误区,特发贴纠正一下,有不同意见的地方尽量提出大家一起讨论,如下语句:(catch语句也和try一样)
------------------------------------------------------------------------
private StringBuilder Test()
{
StringBuilder strb = new StringBuilder("A");
try
{
//这里计算出的结果是"AB",但最终的返回结果是"ABC"
return strb.Append("B");
}
finally
{
//这里的strb.ToString()应该是"AB"
MessageBox.Show("finally:"+strb.ToString());
strb.Append("C");
}
}
------------------------------------------------------------------------
顺序:
在try中的return语句执行,然后执行finally块,最后返回结果。详细:
return语句执行,即执行了strb的Append("B")方法,所以finally块中strb的值为"AB"。
但并不是马上返回结果,而是再转向finally块,因此strb.Append("C")得以执行。strb的值变成"ABC"。
执行完finally后再转到try中的return返回对象strb的最终值"ABC",而不是"AB"。更不是"ACB"。[C#]中finally块不可以有return语句。
[Java]中若finally块出现return则覆盖try,catch语句的return。
------------------------------------------------------------------------
private StringBuilder Test()
{
StringBuilder strb = new StringBuilder("A");
try
{
//这里计算出的结果是"AB",但最终的返回结果是"ABC"
return strb.Append("B");
}
finally
{
//这里的strb.ToString()应该是"AB"
MessageBox.Show("finally:"+strb.ToString());
strb.Append("C");
}
}
------------------------------------------------------------------------
顺序:
在try中的return语句执行,然后执行finally块,最后返回结果。详细:
return语句执行,即执行了strb的Append("B")方法,所以finally块中strb的值为"AB"。
但并不是马上返回结果,而是再转向finally块,因此strb.Append("C")得以执行。strb的值变成"ABC"。
执行完finally后再转到try中的return返回对象strb的最终值"ABC",而不是"AB"。更不是"ACB"。[C#]中finally块不可以有return语句。
[Java]中若finally块出现return则覆盖try,catch语句的return。
{
StringBuilder strb = new StringBuilder("A");
try
{
}
catch
{
}
finally
{
}
return result;
}
我一般是这样做...
string Test()
{
StringBuilder strb = new StringBuilder("A");
try
{
//这里计算出的结果是"AB",但最终的返回结果是"ABC"
strb.Append("B");
return strb.ToString();
}
finally
{
//这里的strb.ToString()应该是"AB"
MessageBox.Show("finally:"+strb.ToString());
strb.Append("C");
}
}
这样的话,string str=Test(),你看看接收到的就是AB了,而不是ABC。因为strb.ToString();返回的已经是一个转换后的新的string对象的引用,在return strb.ToString();时其实先创建一个string对象,再将这个对象的引用返回。
--以上调试通过--
这样说不知道大家明白了不?
return strb.Append("B");其实已经就是最终返回的值,不过这里返回的是一个引用,你之所以得到ABC是因为你又在finally中改变了引用的真实对象的值!
private int test()
{
int i = 0;
try
{
i += 1;
return i;
}
catch
{
return i;
}
finally
{
i += 1;
}
}
返回的是1而不是2.
而且这纯粹是一些基础概念的问题,微软在表述上没有任何问题,并且大多数人也能理解正确。finally块中的代码将在离开try块或catch块时执行。而任何一个return语句的执行顺序是:
先计算表达式的结果,然后将结果返回作为调用表达式的值。
只有将结果返回作为调用表达式的值这个步骤才会导致代码离开try块。所以finally执行的时机便在此时。而return后面的表达式的结果是一个临时变量,是一个没有名字的临时变量。你无法通过任何代码来更改这个临时变量的值,因为它没有名字来标识。但,当这个临时变量是引用的时候,你可以利用引用的特性令这个临时变量引用的对象发生改变,但这并没有改变这个临时变量!。实际上在上面的例子中,无论你在finally中写什么代码都不能使得return的返回结果是一个null值,因为你无法改变这个临时变量。
实际上引用和实例的概念到是经常有人搞不清。。
只是你们表达的不同的东西而已,楼主的意思只是提醒大家即使“return了”,“finally块”中的语句还是照样执行,返回一个变化了的ABC只为了更好的指明“finally”被执行了而已。另外2位确是想尽办法让“finally的执行不要影响return的结果”,表达的是不同的方面的事情。你们2位没看明白楼主的意思。大家说的都对。
而楼主的操作因引用来说明问题..我对引用和实例的概念也更好理解了..谢谢
与 return strb //返回一个引用
的不同。楼主强调了“finally”任何情况都会执行,细致,细致。
{
StringBuilder strb = new StringBuilder("A");
try
{
}
catch
{
}
finally
{
}
return result;
}
finally里面的东东,不管什么情况下都会执行的。
以前我就没理解呀。
return (strb.Append("B")); //结果返回strb的引用,是可变的
那么括号中的值很明显就是strb的引用。如果是:
return (strb.Append("B").ToString()); //结果返回"AB"的引用
括号中的值就应该是函数执行之后的String的引用(仍然是引用不是值,因为String类型也是引用类型,只是String类型是固定空间的不可更改的类型,它的每一次表面上的更改是返回一个新的String对象)。我举这个例子目的是强调其执行顺序,而忽略了引用与值类型。我承认前面的说法有误导,呵呵!我的目的主要是指向前段时间的网上比较流行的<Java36道经典面试题>所公布的标准答案,答案中说:
try块执行到return语句时会先转向finally,执行完finally后再执行return语句,这很容易让人产生误解,以为strb.Append会等finally执行完才执行----所以我才取名为[澄清]。欢迎有问题的继续讨论…… ----楼主
值类型则返回其拷贝。
引用类型返回引用。
(其实你仍然可以认为是返回的值的拷贝,只是这个值是一个引用,类似于C++中的指针变量)
String也是一样,只是String是不可变的引用类型,在很多情况下他更像值的行为。 ----楼主
http://www.phoenixtv.com/phoenixtv/72622743014604800/20050511/547996.shtml
谢谢~
Thank you very much~
再帮你顶
在计算完expression后,将要返回的一刹那,先执行finally子句,然后再实际返回。对执行顺序的正确的理解:
在计算完expression后,在返回的一刹那,先实际返回,然后再执行finally子句,然后再最终返回。
是吗?我只是推测。 那么请问Java中的finally中的return覆盖try中的return怎么解释?
另:
[共享3]C#的字符编码的理解,迷惑了我很久:
http://community.csdn.net/Expert/topic/4002/4002354.xml
[共享2]值传递和引用传递的讨论:
http://community.csdn.net/Expert/topic/3999/3999829.xml ----楼主
前面的更改只是因为是引用。
测试代码:class form1
{
static void main()
{
MyInt my = TestBool(); //my.i最终值为2
}
MyInt TestBool()
{
MyInt d = new MyInt(1);
try
{
return d.Do();
}
finally
{
d.Do();
}
}
}public struct MyInt
{
public MyInt(int b)
{this.i = b;}
public MyInt Do()
{
this.i++;
return this;
}
public int i;
}
Java里没有指针的概念,但是如果程序员脑袋里没有指针的概念就成不了合格的Java程序员。
public class test {
public test(){
}
static Object pri(){
StringBuffer b= new StringBuffer("a");
try{
return b.append("B");//这一句和 b.append("B");return b;
效果是一样的,这样写更容易理解
}finally{
b.append("c");
return null;
} }
public static void main(String[] args)throws Exception {
System.out.println(pri());打印为null
}
}
Ivony() ( ) 信誉:100