为啥 1000 == 1000 是 false

2023-12-22 15:37:12

今天跟大家聊一个有趣的话题,在Java中两个Integer对象做比较时,会产生意想不到的结果。

例如:

Integer?a?=?100;
Integer?b?=?100;
System.out.println(a==b);

其运行结果是:true。

而如果改成下面这样:

Integer?a?=?1000;
Integer?b?=?1000;
System.out.println(a==b);

其运行结果是:false。

看到这里,懵了没有?

为什么会产生这样的结果呢?

上面例子中的a和b,是两个Integer对象。

而非Java中的8种基本类型。

8种基本类型包括:

  • byte

  • short

  • int

  • long

  • float

  • double

  • boolean

  • char

Integer其实是int的包装类型。

在Java中,除了上面的这8种类型,其他的类型都是对象,保存的是引用,而非数据本身。

Integer?a?=?1000;
Integer?b?=?1000;

可能有些人认为是下面的简写:

Integer?a?=?new?Integer(1000);
Integer?b?=?new?Integer(1000);

这个想法表面上看起来是对的,但实际上有问题。

在JVM中的内存分布情况是下面这样的:

图片

在栈中创建了两个局部变量a和b,同时在堆上new了两块内存区域,他们存放的值都是1000。

变量a的引用指向第一个1000的地址。

而变量b的引用指向第二个1000的地址。

很显然变量a和b的引用不相等。

既然两个Integer对象用==号,比较的是引用是否相等,但下面的这个例子为什么又会返回true呢?

Integer?a?=?100;
Integer?b?=?100;
System.out.println(a==b);

不应该也返回false吗?

对象a和b的引用不一样。

Integer?a?=?1000;
Integer?b?=?1000;

其实正确的简写是下面这样的:

Integer?a?=?Integer.valueOf(1000);
Integer?b?=?Integer.valueOf(1000);

在定义对象a和b时,Java自动调用了Integer.valueOf将数字封装成对象。

图片

而如果数字在low和high之间的话,是直接从IntegerCache缓存中获取的数据。

Integer类的内部,将-128~127之间的数字缓存起来了。

也就是说,如果数字在-128~127,是直接从缓存中获取的Integer对象。如果数字超过了这个范围,则是new出来的新对象。

文章示例中的1000,超出了-128~127的范围,所以对象a和b的引用指向了两个不同的地址。

而示例中的100,在-128~127的范围内,对象a和b的引用指向了同一个地址。

所以会产生文章开头的运行结果。

为什么Integer类会加这个缓存呢?

答:-128~127是使用最频繁的数字,如果不做缓存,会在内存中产生大量指向相同数据的对象,有点浪费内存空间。

文章来源:https://blog.csdn.net/liu7322/article/details/135149641
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。