为什么Java中1==1为真,而128==128为假?基于享元模式的整数缓存原理分析

news2024/10/19 6:27:40
❃博主首页 : 「码到三十五」 ,同名公众号 :「码到三十五」,wx号 : 「liwu0213」
☠博主专栏 : <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关>
♝博主的话 : 搬的每块砖,皆为峰峦之基;公众号搜索「码到三十五」关注这个爱发技术干货的coder,一起筑基

今天我们来谈谈在Java中可能会让你感到惊讶的事情——为什么有时用==比较数字的行为并不像你期望的那样。

你可能会认为,在Java中比较两个数字时只要值相等它总是会返回true,因为两边的数字都是一样的,对吧?事实证明,在Java中并不总是那么简单。

一个小代码片段来说明这一点:

Integer a = 128;
Integer b = 128;
System.out.println(a == b); // false

Integer x = 1;
Integer y = 1;
System.out.println(x == y); // true

现在来解释一下为什么会发生这种情况,这与Java中的整数缓存有关。让我们深入探讨。

在Java中,对于基本数据类型(如intchar等)的比较,使用的是值比较。而对于对象(如Integer),使用的是引用比较,即比较的是两个引用是否指向同一个对象。然而,对于Integer类型,Java进行了一些特殊的优化,这影响了比较的结果,特别是在自动装箱和拆箱时。

分析

  1. 基本数据类型的比较

    • 对于基本数据类型int1 == 1直接比较的是两个值,因此结果为true
  2. Integer对象的比较

    • Java中的Integer类是一个对象包装类,用于包装基本数据类型int的值。

    • 当使用Integer变量进行比较时(如a == b),比较的是两个对象的引用是否相同,而不是它们包装的值。

    • 然而,Java对Integer类进行了优化,对于值在-128到127之间的Integer对象,Java会缓存这些对象,即当你使用自动装箱(如Integer a = 127;)时,如果值在这个范围内,Java会返回缓存中的对象,而不是创建一个新的对象。

基于享元模式的整数缓存魔力

Integer类在Java中使用了享元模式(Flyweight Pattern)这一设计模式。享元模式是一种对象结构型模式,它运用共享技术有效地支持大量细粒度对象的复用。在享元模式中,由于存在大量的细粒度对象,如果直接创建这些对象,可能会导致内存占用过高,性能下降。因此,享元模式通过共享对象来减少对象的数量,从而降低内存占用,提高性能。

具体说,Integer类在Java中实现了对-128到127之间整数的缓存。当创建这些范围内的Integer对象时,Integer类会返回缓存中的对象,而不是创建一个新的对象。这样做可以大大减少对象的创建数量,提高内存利用率和性能。这种缓存机制正是享元模式的一种应用。

具体情况分析

  • 对于Integer a = 128; Integer b = 128;

    • 因为128不在-128到127的缓存范围内,所以ab分别指向了两个不同的Integer对象,尽管它们的值都是128。
    • 因此,a == b比较的是两个对象的引用,它们不同,所以结果为false
  • 对于Integer x = 1; Integer y = 1;

    • 因为1在-128到127的缓存范围内,所以xy都指向了缓存中的同一个Integer对象。
    • 因此,x == y比较的是两个对象的引用,它们相同(指向同一个对象),所以结果为true

如何正确比较Integer对象

  • 想要比较两个Integer对象所包装的值,而不是它们的引用,应该使用equals()方法:

    Integer a = 128;
    Integer b = 128;
    System.out.println(a.equals(b)); // true,因为比较的是值
    
  • 使用equals()方法可以确保无论Integer对象的值是否在缓存范围内,比较的结果都是基于它们的值,而不是引用。

最后

  • 对于基本数据类型(如int),==操作符比较的是值。
  • 对于对象(如Integer),==操作符比较的是引用。
  • Java对Integer对象进行了缓存优化,对于-128到127之间的值,会返回缓存中的对象。
  • 为了正确比较Integer对象所包装的值,应使用equals()方法。

关注公众号[码到三十五]获取更多技术干货 !

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零开始搭建你的DolphinScheduler分布式任务调度平台实战指南

文章目录 前言1. 安装部署DolphinScheduler1.1 启动服务 2. 登录DolphinScheduler界面3. 安装内网穿透工具4. 配置Dolphin Scheduler公网地址5. 固定DolphinScheduler公网地址 前言 本篇教程和大家分享一下DolphinScheduler的安装部署及如何实现公网远程访问&#xff0c;结合内…

React速成

useRef获取DOM 组件通讯 子传父 function Son({ onGetMsg }){const sonMsg this is son msgreturn (<div>{/* 在子组件中执行父组件传递过来的函数 */}<button onClick{()>onGetMsg(sonMsg)}>send</button></div>) }function App(){const getMsg…

厨房老鼠数据集:掀起餐饮卫生监测的科技浪潮

厨房老鼠数据集&#xff1a;掀起餐饮卫生监测的科技浪潮 摘要&#xff1a;本文深入探讨了厨房老鼠数据集在餐饮行业卫生管理中的重要性及其相关技术应用。厨房老鼠数据集通过收集夜间厨房图像、老鼠标注信息以及环境数据&#xff0c;为深度学习模型提供了丰富的训练样本。基于…

两个案例全面阐述全链路测试怎么做

首先我们先针对全链路功能测试部分进行一下讲解。去年的时候&#xff0c;有一家电商公司可能知道我一直在帮银行做相关的测试&#xff0c;就请我帮他们去做一些规划。这个平台有虚拟订单&#xff0c;也有实体订单&#xff0c;方式不太一样。 还涉及到分账分佣以及跟银行的对接…

基于SpringBoot+Vue+uniapp的涪陵区特色农产品交易系统的详细设计和实现(源码+lw+部署文档+讲解等)

详细视频演示 请联系我获取更详细的视频演示 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…

【IC设计】复旦微行业分析

文章目录 概述各产品线安全与识别芯片&#xff1a;非挥发存储器&#xff1a;智能电表 MCU &#xff1a;集成电路测试服务&#xff1a; 前景公司是FPGA领军企业&#xff0c;在国产替代背景下深度受益优势 1&#xff1a;公司最早推出亿门级 FPGA 产品&#xff0c;提前卡位 28nm 赛…

python的多线程和多进程

首先需要明确的是&#xff0c;多进程和其他语言的一样&#xff0c;能够利用多核cpu&#xff0c;但是python由于GIL的存在&#xff0c;多线程在执行的时候&#xff0c;实际上&#xff0c;每一时刻只有一个线程在执行。相当于是单线程。然而多线程在某些情况下&#xff0c;还是能…

爬虫逆向-js进阶

1.作用域和闭包 //作用域 // var a 3 // // function test(a){ // var a 1; // console.log(函数内部,a) // } // test(2) // // console.log(a)//闭包 // function jiami(){ // function encrypt(){ // console.log(在这里进行加密了) // } // p…

GaussDB高智能--自治运维技术(中)

目录 2.4 日志分析 &#xff08;1&#xff09;日志解析阶段 &#xff08;2&#xff09;日志分析模型的训练 &#xff08;3&#xff09;在线检测模块 2.5 慢SQL发现 &#xff08;1&#xff09;训练阶段 &#xff08;2&#xff09;预测流程 2.6 慢SQL诊断 &#x…

只想简单跑个 AI 大模型,却发现并不简单

之前我用 Ollama 在本地跑大语言模型&#xff08;可以参考《AI LLM 利器 Ollama 架构和对话处理流程解析》&#xff09;。这次想再捣鼓点进阶操作&#xff0c;比如 fine-tuning。 我的想法是&#xff1a;既然有现成的大模型&#xff0c;为什么不自己整理些特定领域的数据集&am…

如何捕捉行情爆发的前兆

在金融市场的激烈角逐中&#xff0c;每一次行情的爆发都是投资者获取丰厚回报的关键时刻。然而&#xff0c;如何识别并把握这些时刻&#xff0c;却是一门需要深厚金融专业知识和敏锐洞察力的艺术。今天&#xff0c;我们就来深入探讨行情爆发的初期信号&#xff0c;揭示那些能够…

锥线性规划【分布鲁棒、两阶段鲁棒方向知识点】

1 锥线性对偶理论 本部分看似和分布鲁棒、两阶段鲁棒优化没什么关系&#xff0c;但值得优先学习&#xff0c;原因将在最后揭晓。 二阶锥 二阶锥&#xff08;second-order cone&#xff0c;又称ice-cream/Lorentz cone&#xff09;的形式为&#xff1a; 非负象限锥 半正定锥 …

初入Linux网络

1.网络发展 独立模式&#xff1a;计算机之间相互独立——>网络互联&#xff1a;多台计算机连接在一起完成数据共享——>局域网LAN&#xff1a;更多的计算机通过交换机和路由器连接在一起——>广域网WAN&#xff1a;将相隔万里的计算机连在一起。 2.协议 计算机之间…

【AI论文精读5】知识图谱与LLM结合的路线图-P3

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】 P1&#xff0c;P2&#xff0c;P4 5 LLM增强的知识图谱 知识图谱&#xff08;KGs&#xff09; 以其结构化的方式呈现知识而闻名&#xff0c;它们已被广泛应用于许多下游任务&#xff0c;如问答系统、推荐系统和网页搜索等…

(一)Mysql篇---Mysql整体架构

MySql框架浅析 首先&#xff0c;上一张图先让各位看看大致结构&#xff1a; 从上到下&#xff0c;依次说一下结构&#xff1a; 连接层&#xff1a;这里主要是处理客户端和数据库连接的&#xff0c;直接使用的Tomcat的连接池&#xff0c;可以调整最大连接数&#xff1b; 服务…

OpenEuler 软件安装与服务管理全攻略

在 OpenEuler 操作系统的日常使用中&#xff0c;软件安装和服务管理是至关重要的操作环节。本文将以严谨的方式为大家详细阐述 OpenEuler 中安装软件的多种方法&#xff0c;涵盖 RPM、DNF 的概念与操作命令以及操作实验&#xff0c;同时还包括源代码软件的安装方法和使用 syste…

JDK-23与JavaFX的安装

一、JDK-23的安装 1.下载 JDK-23 官网直接下载&#xff0c;页面下如图&#xff1a; 2.安装 JDK-23 2.1、解压下载的文件 找到下载的 ZIP 文件&#xff0c;右键点击并选择“解压到指定文件夹”&#xff0c;将其解压缩到您希望的目录&#xff0c;例如 C:\Program Files\Java\…

react18中如何实现同步的setState来实现所见即所得的效果

在react项目中&#xff0c;实现添加列表项&#xff0c;最后一项自动显示在可视区域范围&#xff01;&#xff01; 实现效果 代码实现 import { useState, useRef } from "react"; import { flushSync } from "react-dom"; function FlushSyncRef() {con…

MySQL面试专题-索引

一、MySQL为什么要选择B树来存储索引&#xff1f; MySQL的索引选择B树作为数据结构来进行存储&#xff0c;其本质原因在于可以减少IO次数&#xff0c;提高查询效率&#xff0c;简单来说就是保证在树的高度不变的情况下可以存储更多的数据。 &#xff08;一&#xff09;IO角度 在…

【状态机DP】【记忆化搜索及翻译递推】【空间优化】力扣3290. 最高乘法得分

给你一个大小为 4 的整数数组 a 和一个大小 至少为 4 的整数数组 b。 你需要从数组 b 中选择四个下标 i0, i1, i2, 和 i3&#xff0c;并满足 i0 < i1 < i2 < i3。你的得分将是 a[0] * b[i0] a[1] * b[i1] a[2] * b[i2] a[3] * b[i3] 的值。 返回你能够获得的 最大…