public class Test {
public static int i = 0; public static int exception(){
try {
throw new Exception();
}catch(Exception e){
return ++i;
}finally{
System.out.println("finally " + ++i);
return ++i; //行100
}
} public static void main(String[] args){
System.out.println("main " + Test.exception());
System.out.println("over " + Test.i);
}}不用编译器,看看你能不能给出正确的输出结果。如果去掉 “行100”这行代码,结果又如何?这题偶做错了...
这个题出的不是很好,但作为校验基本功还算可以。
解决方案 »
- 对象逻辑ID到内存物理地址之间的映射
- JAVA SWING 问题
- java容易混淆的问题
- javabean可以不用包名吗?
- java未来的发展方向,越学越不知道方向了
- applet Runtime问题????
- 怎样在同一个浏览器网页中从一个applet转换到另一个applet,并且传递数据
- 超级高超,超级郁闷,超级难的超级JAVA问题
- 请问在linux下如何让浏览器找到jre,或者java plug in?在windows中可以在控制面版的java plug in 中设置
- jbuilder自带的是jdk1.3版。用1.4版覆盖原来的1.3有问题吗
- Tomcat用eclipse自带的调试工具只能run,不能debug
- 高分求简单数组题目答案
finally2
main3
over3去掉"行100"这行代码时,结果如下:
finally2
main1
over2
finally2
main1
over2
main 3
over 3去掉行100
finally 2
main 1
over 2
main 1
over 2
不去的话是finally 2
main 3
over 2
finally 2
main 3
over 3
2。第二种情况:
finally 2
main 1
over 2
++i是先加后用,i++是先用后加,try..catch..finally的顺序是先try,有问题catch,最后都到finally
你可以把++i,改为i++,运算是不同的并且老实讲,这种题只能当做考题了,没有实际的意义,搞到很弯弯绕的,麻烦
finally2
main3
over3分析:
1. 当执行 System.out.println("main " + Test.exception());这句话时候,访问类的静态方法,此时类是第一次使用,java解释器查找 classPath ,定位Test.class文件,然后将其载入到JVM中,生成Class对象,此时所有该类有关的静态初始化动作就都会执行,包括静态方法和静态成员。这种初始化只在Class对象首次加载时。 此时先执行
public static int i=0 //此时i=0然后接下来是静态方法exception,在try中抛出了异常并被catch住,执行return ++i 此时i值为1,返回1。但因为有了fianllly方法,继续执行 System.out.println("finally " + ++i);
此时打印finally 2,因为又执行了++i的操作,然后return ++i 又执行了一次自增,此时i=3 并且再重新被返回3。
exception返回的结果就是3所以System.out.println("main " + Test.exception()); 执行结果就是 main 3
System.out.println("over " + Test.i); //执行结果就是over 3-------------------------------
没有行100 这句时 更好理解了
执行结果:
finally 2
main 1
over 2按照上面的步骤,当在main中执行test.exception()
执行静态化的部分,i被赋值为0然后执行exception方法,抛出异常,然后被catch住了,执行catch中 return ++i 此时i为1,将1返回。然后再执行finally中的 System.out.println("finally " + ++i); i先被自增为2 然后打印出来 finally 2以上初始执行完后,
在调用 System.out.println("main " + Test.exception());时,结果是main 1
System.out.println("over " + Test.i); 的结果是over 2 (i已经被自增为2了)
main 3
over 3
finally 2
main 1
over 2
}finally{
System.out.println("finally " + ++i);
return ++i; //行100
}
有 finally 肯定会先返回...
主要是搞清楚 try-catch-finally的执行顺序(曾经有篇文章说return语句在try-catch-finally3处多有的情况下,说try-catch里不执行的。个人认为是错误,主要是传统观念误导的,以为一个方法内return语句(嵌在try-catch中)执行后下面功能就结束了(在没有finally情况下是对的))
注意:finally 的作用是,不管方法发不发生"异常"都会被执行
我们throw new Exception();后可以在catch{...}中继续执行,执行完catch{...}后在finally{...}中继续执行;
那么可以这么理解,我们在try-catch里return ;可以在finally{...}中继续执行;
最后就一句话:finally语句块是try-catch-finally最后执行的语句块,其他按语句块常规顺序执行
实际上,finally即不在return前执行,也不在return 后执行,而是在return 中执行。
具体说,return 语句执行时,先将返回值压栈,然后执行finally块,执行完毕后进行返回跳转,再从栈里得到的返回值,其实是finally执行前就压入的那个返回值。
System.out.println("main " + Test01.exception());
首先执行这个代码,然后方法调用进入新的栈Test01.exception()
然后执行try{}中的代码,try{}抛出了一个异常,则执行catch(){}
代码块,将会返回++i的值,当然这个时候i就变成了1了,如果不明白(++i和i++的朋友
可以去练练基本功了哈,这里就不说了),而finally是要在返回之前执行的,所以此时
System.out.println("finally " + ++i);
将会被执行,出现第一个结果finally2
然后 return ++i执行 返回i=3;
main3 也就得出来了;
最后一个由于i 是static的,所以它存在于stack中的,故而改变了就将永远改变。
特别注明:如果读者有兴趣的话讲i的static去掉的话就会发生改变了,其值就是0;
不知道这么解释是否解释清楚了,如果没有清楚的话,LZ可以找我私聊哈
如果去掉100的代码的时候,那么return就将会发生在catch()中,值得注意的是
return ++i; 这个语句的含义是,return i=i+1; 当try{}抛出了异常后会有这个语句执行,
i=1; 当fianlly 执行后就又会跳转到catch中的return部分了。,而此时做的就是一个return语句
而不会在加了。
}catch(){
}finally{}语句块的执行顺序问题,首先进来的时候,肯定是先走try语句块,当try语句块中遇到错误时,进入catch语句块,不管try语句块有没有遇到exception,finally语句块始终使用执行的。再就是三个语句块中的return语句的顺序问题,当try中有return并且没有抛出exception的话,return后的语句是要执行的,不过在return时,它先要看看后面是否有finally语句块,如果有finally语句块,并且finally语句块中也有return语句的话,try中的return就被finally中的给屏蔽掉了,返回时返回的是finally中的return,如果没有的话,执行完finally语句块之后,返回try中的值,finally中对返回结果没有影响
37楼解释的最本质,也是本题的精华所在。
45楼解释的虽然不长,但也抓住了本质,而且很完整。有些兄弟虽然解释的很长,但都是流水解释,呵呵,恕我直言。其实原题没有 行100 这句代码,是我之后自己加上的。编译器报警告了,不建议在finally中加return语句。因为这样破坏了程序的结构。(因为finally是必须要执行的,除了exit之类的系统命令)
最直接的“破坏”就是在一个方法内return运行了两次(后面的覆盖了前面return的结果)。这破坏了方法唯一return的原则。
finally2
main3
over3
估计跟我一样错这的比较多
关于什么i++ ++i 这题 根本没扯上 有些人 还真是打酱油来着
说明:++i的运算级别最高,遇到执行语句时都先执行它!
E:\t>javac Test.java
E:\t>java Test
finally 2 --首先try块抛出一个新异常ctach肯定捕捉执行return ++1,,此时i==1了;finally块无论如何都执行所以 输出++i ,由于++i运算级别最高所以先加后输出即i==2 结果为 finally2main 3 --最后 return ++1//行100 先执行++i再到return 所以方法exception()的返回值就为3了(执行return后就结束上面catch的return就没有用);over 3 --最后 return ++1//行100 先执行++i再到return 所以变量i的值就为3了。
去掉//行100结果
E:\t>javac Test.javaE:\t>java Test
finally 2 --跟上面的 finally 2 一样main 1 --由于没有了 (行100 的return) 执行catch的return后就返回 1 了,所以方法exception()的返回值就为1了;over 2 --因为下面输出语句还有一个++i 所以输出的值也就是变量i的值及i==2;
++i:指的是先对i进行+,然后再执行
finally2
main3
over3去掉"行100"这行代码时,结果如下:
finally2
main1
over2
同意一楼的看法!!