java 常量池

常量池用于保存在编译期已确定的,已编译的,class文件中的一份数据,它包括了关于类,方法,接口等中的常量,也包括字符串常量。如第一种声明方式,当然也可扩充,执行器产生的常量也会放入常量池,故认为常量池是JVM的一块特殊的内存空间。

用new String()创建的字符串不是常量,不能在编译期就确定,所以new String()创建的字符串不放入常量池中,他们有自己的地址空间。

String  s1 = “text”;

String s2 = “text”;

String s2 = s2+"java";

s1,s2同时指向常量池中的常量值"text",s2=s2+"java",后,s2原先指向一个常量,内容"text”,通过对s2进行+操作后,s2所指向的那个值没有改变,此时s2不指向原来那个变量值了,而指向了另一个String变量,内容为”text java“。原来那个变量还存在于内存之中,只是S2这个变量不再指向他了。

String 对象(内存)的不变性机制会使修改String字符串时,产生大量的对象,因为每次改变字符串,都会生成一个新的String。

java 为了更有效的使用内存,jvm有一块特殊的内存区域,被称为常量池,当编译期遇见String 字符串时,他检查该池内是否已经存在相同的String 字符串,如果找到,就把新变量的引用指向现有的字符串对象,不创建任何新的String 常量对象,没找到再创建新的。所以对一个字符串对象的任何修改,都会产生一个新的字符串对象,原来的依然存在,等待垃圾回收。


如果反汇编以上程序的字节码,可以发现,String a = b + "love"; 的实际实现是:
String a = new StringBuilder().append(b).append("love").toString();
所以其实最后是通过toString()方法返回的对象
再查看API中toString()方法的源代码
可以得出结论,返回的是一个堆中的新的对象

 String xx = "ab";

xx = xx + "cd"; //返回的是一个堆中的新的对象

String x1 = "abcd";//常量池中的对象

所以 if(xx == x1)  xx 和 x1 是不同的对象

String b = "hate";
String a = b + "love";
总共创建3个对象,分别是常量池中的“hate”和“love”,以及堆中的“hatelove”
执行过程分析:
1.类加载时,常量池中创建了2个字符串字面常量"hate"和"love"
2.栈中创建引用b,指向常量池中的"hate"
3.栈中创建引用a,+运算后,堆中创建String对象"hatelove",引用a指向该对象


Integer(http://www.iteye.com/topic/1112923)

和String的对象池一样,几种整数基本类型的包装类型也有对象池机制。 
也就是说用Integer int1 = 30;这种方式声明一个Integer对象时会先在对象池中找有没有值为30的对象,如果有直接拿来用,如果没有则重新创建一个对象放入对象池中。java中“==”是比较值,int1和int2引用的同一个对象,内存地址相同,所以int1==int2结果为true。 
而Integer int4 = new Integer(30);这种方式是重新创建一个Integer对象,不会放入对象池中,所以int4和int5是两个不同对象的引用int4==int5结果为false。 
至于int4==int5+int6,因为涉及到运算,所以都是取的各个Integer对象的intValue,也就是比较的30==30+0,所以为true。 
另外补充一点,对象池中对象的值的在[-128,127]之间,超过此范围的不会在对象池中缓存。也就是说Integer int7 = 130;Integer int8 = 130;判断int7==int8,结果为false。

 

Integer int1 = 30; 
Integer int2 = 30; 
Integer int3 = 0; 
System.out.println(int1 == int2); 
System.out.println(int1 == int2 + int3); 

Integer int4 = new Integer(30); 
Integer int5 = new Integer(30); 
Integer int6 = new Integer(0); 
System.out.println(int4 == int5); 
System.out.println(int4 == int5 + int6); 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值