码迷,mamicode.com
首页 > 编程语言 > 详细

java常量池中基本数据类型包装类的小陷阱

时间:2014-11-01 17:32:33      阅读:339      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   color   ar   java   sp   数据   

     想必大部分学过java的人都应该做过这种题目:

 1 public class Test {
 2     public static void main(String[] args) {
 3         //第一个字符串
 4         String s1="hello";
 5         
 6         //第二个字符串
 7         String s2="hello";
 8         
 9         //比较s1和s2是否相同
10         System.out.println(s1==s2);
11         
12         
13         /**
14          * 修改变量
15          */
16         
17         s1=new String("hello");
18         
19         s2=new String("hello");
20         
21         //再次比较s1和s2是否相同
22         System.out.println(s1==s2);
23     }
24 };

    最后的结果如图:

bubuko.com,布布扣

图一

     对于这个结果,我相信没有人有异议!因为第一组是依靠常量池的结果,即String s1=“hello”时实际会在内存中栈的常量池中创建一个字符串常量“hello”对象,当String s2=“hello”时,因为常量池中已经存在,所以s2会直接指向同一个”hello“对象,也就是s1和s2对象的地址值是一致的,此时的String就有点类似与基本数据类型,所以用“==”来比较的时候,值为“true”。

     而如果String s1=new String("hello")时,s1在堆中开辟出新的内存空间存放“hello”值,同理,s2也会在堆中重新开辟空间存放“hello”值,s1和s2所指向的值的地址不同,用“==”来比较的时候自然是不同的,值为“false”。

     但不知道有多少人做过下面这道题目呢?

     修改一下上题中的变量类型为Integer。

 1 package action;
 2 
 3 public class Test {
 4     public static void main(String[] args) {
 5         //第一个数值
 6         Integer s1=127;
 7         
 8         //第二个数值
 9         Integer s2=127;
10         
11         //比较s1和s2是否相同
12         System.out.println(s1==s2);
13         
14         
15         /**
16          * 修改变量
17          */
18         
19         s1=128;
20         
21         s2=128;
22         
23         //再次比较s1和s2是否相同
24         System.out.println(s1==s2);
25     }
26 };

     你的答案会是什么呢?


     结果图如下:

bubuko.com,布布扣

图二

      是不是有点出乎你的意料呢?

      从原理上来说,Integer和String类型都属于引用类型,那么最后的结果应该和String类型的比较一致,而且就算Integer类型的没有常量池技术那么这两次的结果也应该一致啊,毕竟只是相差1而已!

      这就是我这篇博客要说的java常量池的小陷阱了!

      java中的基本数据类型的包装类有6种实现了常量池技术,他们分别是:Byte , ShortIntegerLong Characher ,Boolean。Double和Float没有实现,佐证如下图:

bubuko.com,布布扣

图三

      直接定义常量是会报错的(这个佐证其实有点不靠谱,如果有谁知道,麻烦告诉一声,谢谢!)

      而在上述所说的6种有常量池技术的包装类中,除了Boolean以外,其他的值都不能超过  127  (小于或者等于) ,超过127常量池就不予自动创建对象,这时包装类就和普通的引用类型没有区别了。

      关于常量池的详细介绍,可以借鉴这篇博客(我也是从中得到原因的):

      http://www.cnblogs.com/qinqinmeiren/archive/2011/07/19/2151683.html

 

 

 

 

 

java常量池中基本数据类型包装类的小陷阱

标签:style   blog   http   io   color   ar   java   sp   数据   

原文地址:http://www.cnblogs.com/liaochong/p/javabase.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!