Integer类型128==128为false?

Why?

为何如下结果为false呢

Integer ic=128;
Integer id=128;
System.out.println("ic==id结果为:"+(ic==id));

这里写图片描述

对于对象引用类型:“==”比较的是对象的内存地址。
对于基本数据类型:“==”比较的是值。
对于这个问题就不得不说一下常量池了。常量池分为静态常量池运行时常量池
静态常量池:即是全局常量池,通常理解为被final修饰的常量。
运行时常量池:是方法区的一部分,用于存放运行时创建的常量。

栗子

Integer ia=127;
Integer ib=127;
Integer ic=128;
Integer id=128;
System.out.println("ia==ib结果为:"+(ia==ib));
System.out.println("ic==id结果为:"+(ic==id));

这里写图片描述
对于Integer对象来说,其能存储常量的范围为(-128~127),超出范围则存储到堆内存中。127和128都是常量,按照正常情况都会在运行时常量池创建,但是Integer对象类型能够存储常量的范围为(-128~127),所以127被创建在运行时常量池中,而128则创建在堆内存中(这里涉及到Java基本数据类型和封装类之间的自动装箱和自动拆箱)。 例子中的ia和ib都指向同一个常量地址;在堆内存中每个变量都会分配一个内存地址,ic和id在堆内存中的存储地址是不一样的,“==”来比较值就是false。

再来举个栗子

String类

1、没有使用new关键字

String sa="hello world!";//在常量池中建立字符串“hello world!”,然后sa指向该常量池地址
String sb="hello world!";//sb指向该常量池地址
String s1="hello ";
String s2="world!";
String sc=s1+s2;
System.out.println("sa==sb结果为:"+(sa==sb));
System.out.println("sa==sc结果为:"+(sa==sc)); 

这里写图片描述
按照之前的分析,字符串“hello world!“会创建在运行时常量池里面,sa和sb用”==“是true,那么sa和sc为何为false呢?
s1和s2都会在运行时常量池里面创建,使用+拼接起来的sc会是什么呢?
将编译好的.class文件反编译如下:

String sa = "hello world!";
String sb = "hello world!";
String s1 = "hello ";
String s2 = "world!";
String sc = (new StringBuilder(String.valueOf(s1))).append(s2).toString();

原来sc是通过StringBuilder来实现拼接的,其指向的是堆内存地址。sa==sc自然是false了。

2、再来看看使用new关键字

String str1=new String("hello world!");
String str2=new String("hello world!");
System.out.println("str1==str2结果为:"+(str1==str2));

这里写图片描述

字符串”hello world! “会被创建在运行时常量池里面,str1和str2是两个不同的对象,内存地址不一样,但是其引用的都是常量池里面的”hello world! “。因此不能用”==“比较。
总结:比较值是否相等对于基本数据类型使用==比较,对于封装类则用equals比较。
收获:浅简的理解了静态常量池和运行时常量池。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值