编译并反编译BeforeFor和InFor,对比如图《javap》,截图中省略了前半部分,只有类名不同。
可见方法中堆大小同样为2,用来存储本地变量str和i;
3个局部变量,分别指向参数args、局部变量str、局部变量i;
一个参数,args
可以看到区别有2处:
1 str和i的存储位置相反
2 Before中的str的作用域为方法体内部,而In中为for循环体内部。
根据字节码可以看出:
引用占用的内存分配时机相同,计算时间相同,占用内存相同。
所谓分配内存时机相同,是说,java编译过程中可以计算出方法一共需要多少局部变量,在运行时要在进入方法时一次性申请全部变量所需引用或基本类型所需的堆大小。
所以我建议
如果变量不需要在循环体外部继续使用,应将声明放在循环体内部,原因如下:
1 从可读性和安全性角度考虑,应尽量减小作用范围,声明写在for内部可以防止变量污染和变量的误用。
2 从性能角度考虑,在不考虑运行时优化的情况,在循环体内部声明的变量在退出循环体后声明任何一个变量(既改变局部变量表,如 int a=1),str就可以被垃圾回收,而声明在循环体前面的变量要在方法结束之后才能被回收。
来自杜天微的私人邮箱
[img]http://dl.iteye.com/upload/attachment/0067/9240/a320358e-c715-310f-bc64-c81979726b1d.png[/img]
(javap.png)
可见方法中堆大小同样为2,用来存储本地变量str和i;
3个局部变量,分别指向参数args、局部变量str、局部变量i;
一个参数,args
可以看到区别有2处:
1 str和i的存储位置相反
2 Before中的str的作用域为方法体内部,而In中为for循环体内部。
根据字节码可以看出:
引用占用的内存分配时机相同,计算时间相同,占用内存相同。
所谓分配内存时机相同,是说,java编译过程中可以计算出方法一共需要多少局部变量,在运行时要在进入方法时一次性申请全部变量所需引用或基本类型所需的堆大小。
所以我建议
如果变量不需要在循环体外部继续使用,应将声明放在循环体内部,原因如下:
1 从可读性和安全性角度考虑,应尽量减小作用范围,声明写在for内部可以防止变量污染和变量的误用。
2 从性能角度考虑,在不考虑运行时优化的情况,在循环体内部声明的变量在退出循环体后声明任何一个变量(既改变局部变量表,如 int a=1),str就可以被垃圾回收,而声明在循环体前面的变量要在方法结束之后才能被回收。
来自杜天微的私人邮箱
[img]http://dl.iteye.com/upload/attachment/0067/9240/a320358e-c715-310f-bc64-c81979726b1d.png[/img]
(javap.png)