当前位置: 代码迷 >> J2SE >> 新手请问常量池和类赋值的内存有关问题
  详细解决方案

新手请问常量池和类赋值的内存有关问题

热度:10   发布时间:2016-04-23 19:58:33.0
新手请教常量池和类赋值的内存问题
如题
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
  相关解决方案