public class test_try {
public int doPrint(){
int a = 0;
try{
a=1;
throw new SQLException();
}
catch(Exception e){
System.out.println("catch_开始");
return a;
}
finally{
System.out.println("finally_开始"+a);
a=3;
System.out.println("finally_完毕"+a);
}
}
public static void main(String[] args) {
test_try t=new test_try();
System.out.println("得到返回的值"+t.doPrint());
}}得到的结果是:
catch_开始
finally_开始1
finally_完毕3
得到返回的值1一般情况下是先执行TRY里面的语句 ,当遇到异常后则执行catch里面的代码,然后再执行finally
那么:结果不是这样的显示方式,应该是return返回2后 然后再回来执行finally ,但是这种方式也不可取,很显然根据显示的结果是这样的执行了try 遇到异常执行catch 里面的System.out.println("catch_开始");然后缓存起return a;(这里的a当然是1了)然后执行finally 里面的了~~最后返回 catch里面执行return a;然后输出a
这里问题就来了。为什么要这样做???请高手解释下 谢谢
1.finally块不管在什么时候都是需要执行的,即使你在try块中return了
2.return其实就是给函数中的一个隐藏变量赋值,所以你在try块中return的值会被finally中return的值覆盖掉。
3.引用类型和值类型的区别,引用类型指向的是同一个对象,一个改变大家都改变。值类型是每个人都有一份大家互不干扰。
StringBuilder是引用类型,所以在finally中改变的值会影响返回值,int是值类型所以再次改变i的值也不会影响到函数的隐藏变量的值!http://topic.csdn.net/u/20090305/20/58898020-d677-4f58-be77-b73e978026af.html?17180
不知道你什么意思,你程序的执行结果是正确的。
1、java中的变量问题:
java中基本类型都是传值,还有一个特殊的对象String对象是不变量,也可以理解为传值吧
public int doPrint() 这个方法的返回值如果是 基本类型或者是 String类型,起返回结果都是在Catch内确定了,因为finally内
的修改都是另一个内存区域内的值public Object doPrint() 如果是对象那么java中是传引用,所以finally做的修改跟catch内做的修改是同一块内存中的数据,这个时候finally内修改就会起作用,如果是返回对象的话,就是楼主理解的那样了2、finally 块内语句 除断电,jvm崩溃,或者System.exit() 不会执行到,其他情况都会先执行finally块内的语句,最后执行return语句
下面是我的测试代码:
public class Fuck { /**
* 测试StringBuffer对象
*
* @return
*/
public static StringBuffer printSB() {
StringBuffer a = new StringBuffer();
try {
a.append("try");
System.out.println("try_开始" + a);
throw new Exception();
} catch (Exception e) {
a.append("catch");
System.out.println("catch_开始" + a); return a; } finally {
a.append("finally");
System.out.println("finally_开始" + a);
}
} /**
* 测试用户对象
*
* @return
*/
public static Stu printObj() {
Stu stu = new Stu(25, "ffshi");
try {
stu.setName("try");
System.out.println("try_开始 " + stu.toString());
throw new Exception();
} catch (Exception e) { stu.setName("catch");
System.out.println("catch_开始 " + stu.toString());
return stu; } finally {
stu.setName("finally");
System.out.println("finally_开始 " + stu.toString()); }
} public static void main(String[] args) {
System.out.println(printSB());
// try_开始try
// catch_开始trycatch
// finally_开始trycatchfinally
// trycatchfinally
System.out.println(printObj().toString());
// try_开始 age:25 name:try
// catch_开始 age:25 name:catch
// finally_开始 age:25 name:finally
// age:25 name:finally
}}class Stu {
@Override
public String toString() {
// TODO Auto-generated method stub
return "age:" + age + " name:" + name;
} int age;
String name; public Stu(int age, String name) {
this.age = age;
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}}
1.执行try里面的语句,
2.如果有异常执行catch语句,注意如果catch中有return语句,应该先执行finally语句再返回执行return语句。
3.不管是否有异常,都要执行finally语句所以当前程序的结果很正常!
除非 突然掉电,系统崩溃或JVM崩溃,调用到system.exit.不然是不可能不执行finally
其实在编程中,finally 一般不要给变量赋值,它的一个主要作用是释放占用的资源。
public class test_try {
public int doPrint(){
int a = 0;
try{
a=1;
throw new SQLException();
}
catch(Exception e){
System.out.println("catch_开始");
//return a; 不应此处返回
}
finally{
System.out.println("finally_开始"+a);
a=3;
System.out.println("finally_完毕"+a);
}
return a; //应此处返回
}
public static void main(String[] args) {
test_try t=new test_try();
System.out.println("得到返回的值"+t.doPrint());
}}
public int doPrint(){
int a = 0;
try{
a=1;
throw new SQLException();
}
catch(Exception e){
System.out.println("catch_开始");
//return a; 不应此处返回
}
finally{
System.out.println("finally_开始"+a);
a=3;
System.out.println("finally_完毕"+a);
}
return a; //应此处返回
}
public static void main(String[] args) {
test_try t=new test_try();
System.out.println("得到返回的值"+t.doPrint());
}}
在finally中改变return的值对返回值没有任何影响,而对于引用类型的数据,就有影响。
所以结果a=1
最后的System.err.println是在main里面的,所以打印出来的只是return的值,至于在后面继续改了这个变量,变量
确实改变了,但你return的不是更改后的值,做了简单两个小测试,大家可以试一下。我用的jdk是1.4.2,
还有一种说法是因为int型是值类型,用Integer就不一样了,我用String类型同样试了一下,结果还是如此。
import java.lang.*;
public class A
{
public static void main(String[] args)
{
A a = new A();
System.err.println(a.gets());
}
public int gets(){
try{
throw new Exception();
}catch(Exception e){
return 1;
}finally{
return 2;
}
}
public int gets2(){
int i= 2;
try{
throw new Exception();
}catch(Exception e){
//return 1;
i=1;
}finally{
//return 2;
i=3;
}
return i;
}
public String gets3(){
String i= "a";
String b="e";
try{
throw new Exception();
}catch(Exception e){
//return 1;
i="b";
return i;
}finally{
//return 2;
i=b;
}
//return i;
}
}
catch_开始
finally_开始1
finally_完毕3
得到返回的值1如果改为
public class test_try {
public int doPrint(){
int a = 0;
try{
a=1;
throw new SQLException();
}
catch(Exception e){
System.out.println("catch_开始");
return a;
}
finally{
System.out.println("finally_开始"+a);
a=3;
System.out.println("finally_完毕"+a);
return a;
}
}
public static void main(String[] args) {
test_try t=new test_try();
System.out.println("得到返回的值"+t.doPrint());
}}结果是:
catch_开始
finally_开始1
finally_完毕3
得到返回的值3
分析下……
----catch,前面跑出个异常,所有就要catch一下
----return,catch里有return 就要执行阿 返回1
然后停住去执行finally,注意,返回值已经返回了就是1,不是a
----finally,这个必须执行,最后就要执行.