例如:
一:
for(int i=0;i<1000;i++){
Integer i = new Integer(i);
System.out.println(i.intValue());
}
这里需要把 Integer i 定义在for 循环外面,变成二:
Integer i = null;
for(int i=0;i<1000;i++){
i = new Integer(i);
System.out.println(i.intValue());
}二的写法开销会不会更小?一的写法编译器编译后的代码回自动优化成二的吗?
一:
for(int i=0;i<1000;i++){
Integer i = new Integer(i);
System.out.println(i.intValue());
}
这里需要把 Integer i 定义在for 循环外面,变成二:
Integer i = null;
for(int i=0;i<1000;i++){
i = new Integer(i);
System.out.println(i.intValue());
}二的写法开销会不会更小?一的写法编译器编译后的代码回自动优化成二的吗?
第二,不认为这两种写法有什么区别,反倒是第二种写法,还要多一个null压栈的操作...
局部变量名不过是程序员用于区分变量的标识符, 而虚拟机不需要.如果真要想要Integer减少开销,
用Integer i = 22;
或者Interger i = Integer.valueOf(22);
这种写法,
valueOf对[-128, 127]有缓存
-------java高手群44491863-------
for(int i=0;i<1000;i++){
Integer x = new Integer(i);
System.out.println(x.intValue());
}
这里需要把 Integer x 定义在for 循环外面,变成二:
Integer x = null;
for(int i=0;i<1000;i++){
x = new Integer(i);
System.out.println(x.intValue());
}二的写法开销会不会更小?一的写法编译器编译后的代码回自动优化成二的吗?
分配一个4字节的指针,与构造对象相比,消耗是很小的。
jvm可以对一些程序进行运行期优化。
for(int i=0;i<1000;i++){
Integer x = new Integer(i);
System.out.println(x.intValue());
}
对应的jvm指令为:
0: iconst_0
1: istore_1
2: iload_1
3: sipush 1000
6: if_icmpge 34
9: new #2; //class java/lang/Integer
12: dup
13: iload_1
14: invokespecial #3; //Method java/lang/Integer."<init>":(I)V
17: astore_2
18: getstatic #4; //Field java/lang/System.out:Ljava/io/PrintStream;
21: aload_2
22: invokevirtual #5; //Method java/lang/Integer.intValue:()I
25: invokevirtual #6; //Method java/io/PrintStream.println:(I)V
28: iinc 1, 1
31: goto 2
34: return
-----------------------------------------------
Integer x = null;
for(int i=0;i<1000;i++){
x = new Integer(i);
System.out.println(x.intValue());
}
对应指令为:
0: aconst_null
1: astore_1
2: iconst_0
3: istore_2
4: iload_2
5: sipush 1000
8: if_icmpge 36
11: new #2; //class java/lang/Integer
14: dup
15: iload_2
16: invokespecial #3; //Method java/lang/Integer."<init>":(I)V
19: astore_1
20: getstatic #4; //Field java/lang/System.out:Ljava/io/PrintStream;
23: aload_1
24: invokevirtual #5; //Method java/lang/Integer.intValue:()I
27: invokevirtual #6; //Method java/io/PrintStream.println:(I)V
30: iinc 2, 1
33: goto 4
36: return
你可以比较一下区别.
这就是我为什么说用后一种写法还要多出个null来.
另外,这些都是在编译时候已经决定的,写在.class文件里面的.而jvm只会和.class文件打交道.
他会严格按照这些指令执行,而不是.java文件写的内容.