为啥 1000 == 1000 是 false

今天跟大家聊一个有趣的话题,在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是使用最频繁的数字,如果不做缓存,会在内存中产生大量指向相同数据的对象,有点浪费内存空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/292645.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【动画图解】一次理清九大排序算法!面试官问到再也不慌!

排序算法 交换排序 冒泡排序快速排序 插入排序 直接插入排序希尔排序 选择排序 简单选择排序堆排序 归并排序基数排序桶排序 一、冒泡排序 冒泡排序是一种简单的交换排序算法,以升序排序为例,其核心思想是: 从第一个元素开始&#xff0c…

.NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式

之前写过使用自定义返回类的方式来统一接口数据返回格式,.Net Core webapi RestFul 统一接口数据返回格式-CSDN博客 但是这存在一个问题,不是所有接口会按照定义的数据格式返回,除非每个接口都返回我们自定义的类,这种实现起来不…

解决IDEA编译/启动报错:Abnormal build process termination

报错信息 报错信息如下: Abnormal build process termination: "D:\Software\Java\jdk\bin\java" -Xmx3048m -Djava.awt.headlesstrue -Djava.endorsed.dirs\"\" -Djdt.compiler.useSingleThreadtrue -Dpreload.project.path………………很纳…

Valentina Studio Pro for Mac:高效数据库管理工具

作为一款强大而高效的数据库管理工具,Valentina Studio Pro for Mac在Mac平台上的表现无疑是令人印象深刻的。无论您是初学者还是专业数据库管理员,Valentina Studio Pro都能够满足您的需要,并提供一流的工具和功能来简化数据库管理的过程。 …

linux静态ip配置方法(vmware虚拟机)

1、背景 自己搭建了一个虚拟机,vmware虚拟机,如果使用动态ip,经常变换地址,登录不方便。 优点: 静态网络配置的好处是该服务器地址是静态ip的,不会随着网络更换而出现波动。 2、配置方法 2.1 进入centos系统&#…

HarmonyOS 应用事件打点开发指导

简介 传统的日志系统里汇聚了整个设备上所有程序运行的过程流水日志,难以识别其中的关键信息。因此,应用开发者需要一种数据打点机制,用来评估如访问数、日活、用户操作习惯以及影响用户使用的关键因素等关键信息。 HiAppEvent 是在系统层面…

C++之深拷贝和浅拷贝

目录 浅拷贝 深拷贝 赋值运算符重载的深拷贝 在学习C类和对象时我们学习了浅拷贝,本期我们将再次回顾浅拷贝并为大家讲述深拷贝的概念。 浅拷贝 在学习类和对象时我们学习了拷贝构造函数的概念,而且我们也知道,因为拷贝构造函数属于类的默…

用 树莓派 做成巨型的 Game Boy 你见过吗?

​几年前,华纳斯科奇(Warner Skoch)萌生了3D打印巨型Game Boy想法。他最初的计划是把它挂在墙上,用一个时钟作为屏幕,就像一件艺术品一样。后来,他的工匠头脑开始活跃起来,开始考虑通过添加 Ras…

3_js数组与函数的应用

1. 数组的应用 1.1 数组的概念 在计算机科学中,数组数据结构(英语:array data structure),简称数组(英语:Array),是由相同类型的元素(element)的…

MySQL undo日志精讲2-undo日志写入

通用链表结构 在写入undo日志的过程中会使用到多个链表,很多链表都有同样的节点结构,如图所示: 在某个表空间内,我们可以通过一个页的页号和在页内的偏移量来唯一定位一个节点的位置,这两个信息也就相当于指向这个节点…

基于Java+Swing实现大鱼吃小鱼小游戏(含用户登陆、注册功能)

基于JavaSwing实现大鱼吃小鱼小游戏 一、系统实现二、功能展示1.效果演示2.游戏界面3.游戏运行界面4.用户登陆 三、其他系统四源码下载 一、系统实现 1、创建窗口对象Ui 2、背景的绘制 3、键盘的监听事件 4、将己方鱼放上去 5、让小鱼移动 6、其他的鱼并引导(先创建…

用户管理第2节课--idea 2023.2 后端--实现基本数据库操作(操作user表) -- 自动生成

一、插件 Settings... 1.1 File -- Settings 1.2 Settings -- Plugins 1.2.1 搜索框,也可以直接搜索 1.3 Plugins -- 【输入 & 搜索】mybatis 1.3.1 插件不同功能介绍 1.3.2 翻译如下 1.4 选中 Update,更新下 1.4.1 更新中 1.4.2 Restart IDE 1…