java问题,循环外定义变量和循环内定义变量
for(inti=0;i<100;i++){Objectobj=newObject();}和Objectobj;for(inti=0;i<100;有什么区别,是不是第二种...
for (int i = 0; i < 100; i++) { Object obj = new Object(); } 和 Object obj; for (int i = 0; i < 100;
有什么区别,是不是第二种能够重用obj这个指针?
我反编译的两段代码,生成的字节码不是很看的懂,大家讨论下如何?
Code:
0: iconst_0
1: istore_2
2: goto 16
5: new #3; //class java/lang/Object
8: dup
9: invokespecial #8; //Method java/lang/Object."<init>":()V
12: astore_1
13: iinc 2, 1
16: iload_2
17: bipush 100
19: if_icmplt 5
22: return
Code:
0: iconst_0
1: istore_1
2: goto 16
5: new #3; //class java/lang/Object
8: dup
9: invokespecial #8; //Method java/lang/Object."<init>":()V
12: astore_2
13: iinc 1, 1
16: iload_1
17: bipush 100
19: if_icmplt 5
22: return
第一种代码剪短写,维护性好,如果指针可以重用那么第一种最好了,
第二种代码行数多,但是如果可以重用指针,那么性能最好
这个是我的理解,我以前都是按照第二种写的代码,但是变量多的时候代码太长了,所以想大家讨论一下
大家回答的时候看仔细,作用域是相同的!!!
主要是有没有重用obj这个指针,大家说详细点 展开
有什么区别,是不是第二种能够重用obj这个指针?
我反编译的两段代码,生成的字节码不是很看的懂,大家讨论下如何?
Code:
0: iconst_0
1: istore_2
2: goto 16
5: new #3; //class java/lang/Object
8: dup
9: invokespecial #8; //Method java/lang/Object."<init>":()V
12: astore_1
13: iinc 2, 1
16: iload_2
17: bipush 100
19: if_icmplt 5
22: return
Code:
0: iconst_0
1: istore_1
2: goto 16
5: new #3; //class java/lang/Object
8: dup
9: invokespecial #8; //Method java/lang/Object."<init>":()V
12: astore_2
13: iinc 1, 1
16: iload_1
17: bipush 100
19: if_icmplt 5
22: return
第一种代码剪短写,维护性好,如果指针可以重用那么第一种最好了,
第二种代码行数多,但是如果可以重用指针,那么性能最好
这个是我的理解,我以前都是按照第二种写的代码,但是变量多的时候代码太长了,所以想大家讨论一下
大家回答的时候看仔细,作用域是相同的!!!
主要是有没有重用obj这个指针,大家说详细点 展开
展开全部
两者相同点:每次初始化这个obj时都是重新new一个对象,因此效率上应该没什么区别。两者不同点:循环内定义的变量的可用范围显然比循环外定义的变量的范围小,循环内定义的变量会在循环结束后,java垃圾回收机制自动销毁该变量,释放其所占用的内存,而循环外定义的变量则需要在方法返回时去销毁对象,释放内存。所以,如果只是临时的变量,还是循环内定义好些,这样java就不用管理那么多没用的变量了。
追问
你错了,我这个变量虽然是定义在循环外,但是初始化是在循环内,所以作用域,释放内存等等都是相同的
我的问题是,我觉得第2种写法重用了指针,应该是最优的写法,想讨论下,到底是不是,记得以前好像看sun的文章说过,第二种是最优的
展开全部
编译成字节码后没有区别,
虽然Object obj放在for内还是for外,从源码层面有个域的区别,但在编译器时优化了,区别在字节码上不存在。
其他因素参与后,编译器会相应调整。语法通不过编译不出来,而编译出来的都优化过了。
虽然Object obj放在for内还是for外,从源码层面有个域的区别,但在编译器时优化了,区别在字节码上不存在。
其他因素参与后,编译器会相应调整。语法通不过编译不出来,而编译出来的都优化过了。
更多追问追答
追问
编译后有区别的吧?好像是堆栈的顺序不同,我的问题是,第1种方法有没有重用指针
另外,源码层面我这个变量虽然定义在循环外面,但是没有初始化,所以作用域是没有区别的
追答
顺序由于有快捷位置_0 _1 _2这些在所给的字节码中可以忽略了。
是否“重用指针”,事实是前一例把对象地址存在_1位置,后一例在_2位置。都在反复使用相应的地址位置。执行时也许前者用ebx,后者用ecx寄存器,也许栈的固定位置。
源码层面,变量定义放在域内外有明显区别。域本身是个高级概念,作为编译规则存在吧。在某方法内的字节码层面是模糊的。
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
2012-02-17
展开全部
看了上面2个回答哦 我发现了问题 其实系这个lz基础太差..半桶水晃荡啦..扯到字节码..作用域都没理解对 2个{}不同 obj不是指针..怎么说详细..还要说别人错,自己懂.... 楼猪还是做些基本的题吧..
追问
如果代码按照我原来的那样,那么循环完了之后,obj引用就已经失效了,所以内存回收上一样的,第二种写法应该不是方法完成后才释放内存
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询