如题
public class test {
public static void main(String[] args){
Integer i = new Integer(1);
i = 2;
System.out.println( i );
}
}
1、关于 i = 2 这里,i 是索引,2 是值,不使用构造方法赋值怎样做到的?(为什么我写一个类却不能被直接赋值.....)
2、这里 2 应该是放在常量池里面的,如果我要给 i 赋1000个不同的值,那内存岂不是压力很大?栈变量随函数结束释放,堆里面对象有垃圾回收站,那么堆里的常量池里的内存释放机制是什么?
------解决思路----------------------
1、关于 i = 2 这里,i 是索引,2 是值,不使用构造方法赋值怎样做到的?(为什么我写一个类却不能被直接赋值.....)
:不使用构造方法就直接全局变量赋值啊:public Integer i = new Integer(1);
2、这里 2 应该是放在常量池里面的,如果我要给 i 赋1000个不同的值,那内存岂不是压力很大?栈变量随函数结束释放,堆里面对象有垃圾回收站,那么堆里的常量池里的内存释放机制是什么?
:谁说2是放在常量池里边的?java中的运行时常量池指的是String相关,而堆和常量池里的变量回收都是有Full GC 负责的!
------解决思路----------------------
1、关于 i = 2 这里,i 是索引,2 是值,不使用构造方法赋值怎样做到的?(为什么我写一个类却不能被直接赋值.....)
不必使用构造方法,当i需要被解析的时候直接把2从常量池中拷贝过来。
2、这里 2 应该是放在常量池里面的,如果我要给 i 赋1000个不同的值,那内存岂不是压力很大?栈变量随函数结束释放,堆里面对象有垃圾回收站,那么堆里的常量池里的内存释放机制是什么?
常量池中的2不会被回收,函数栈帧中的2才会随着方法结束而被回收。
------解决思路----------------------
i = 2; 实际上是调用Integer.valueOf(int i) 方法,看Integer类的源码就知道,这个方法中,如果i的值在-128~127之间,则直接从缓存中获取,如果超出这个范围则是new的
------解决思路----------------------
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/lang/Integer
3: dup
4: iconst_1
5: invokespecial #3; //Method java/lang/Integer."<init>":(I)V
8: astore_1
9: iconst_2
10: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
13: astore_1
14: return
}
我根据字节码来解释吧。
首先创建Integer对象,然后常量放入操作栈,执行初始化方法,然后赋值给局部变量。然后第二个常量,2,入栈,执行Integer.valueOf方法,赋值给局部变量
1和2是放在常量池中的。举个例子你用javap看一下,可以清楚的看到。iconst_1和最后一个iconst_1是一个常量。
int a=1;
a=2;
a=3;
a=1;
0: iconst_1
1: istore_1
2: iconst_2
3: istore_1
4: iconst_3
5: istore_1
6: iconst_1
7: istore_1
8: return