java中定义常量使用包装类型吗_java常量池中基本数据类型包装类的小陷阱

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

1 public classTest {2 public static voidmain(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 };

最后的结果如图:

fa7fab54a99e4981bf0689200477a61e.png

图一

对于这个结果,我相信没有人有异议!因为第一组是依靠常量池的结果,即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 packageaction;2

3 public classTest {4 public static voidmain(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 };

你的答案会是什么呢?

结果图如下:

007c095dd225fdc50654e9f1a7667e54.png

图二

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

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

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

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

1b713c40ba9490cb1c0cda2fc44aa0d8.png

图三

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

这5种包装类在常量池的实现上与String有点区别,以Integer为例,当有Integer i=127时,实际上发生了如下操作:

Integer i=Integer.valueOf(127)

Integer.valueOf()方法基于减少对象创建次数和节省内存的考虑,缓存了[-128,127]之间的数字。此数字范围内传参则直接返回缓存中的对象。在此之外,直接new出来.

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

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

关于Integer.valueOf()可以参考这篇:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值