LongCache机制与Long等值比较

Java数据类型—包装类 1. 为什么需要包装类:JAVA是面向对象的语言,很多类和方法中的参数都需使用对象(例如集合),但基本数据类型却不是面向对象的,这就造成了很多不便 2. 拆装箱的概念:将基本数据类型转为包装类的过程叫装箱,将包装类转为基本数据类型的过程叫拆箱 3. 自动拆装箱:Java为了简便拆箱与装箱的操作,提供了自动拆装箱的功能 4. 建议使用valueOf() 方法创建一个包装类实例而不是直接使用构造方法,因为该方法可以走缓存提高性能 阅读详情

一、背景引入
近期在开发一个项目的后台时,当项目上线后出现了一个测试环境没有出现的问题:部分用户在提交信息时提示了该信息不属于当前用户。
经过对代码的review,发现了出错的代码的开发逻辑是,在用户提交信息之后,将信息更新入数据库之前,首先判断当前的信息是否属于当前的用户;通过信息.account_id == 用户.id进行了判断,两个id都是Long类型。直觉是使用==号出错的问题,于是将此处的代码修改为先使用Long.longValue()取出来,再进行比较。(或者使用Long.equals()方法亦可)
然而有一个相当有趣的情况,那就是测试环境并没有这样的问题。究其原因,竟是因为Long类型的LongCache机制引起,且因为测试环境的模拟用户数据量较少,没有突破LongCache内部缓存数组的边界,导致该问题没能及时在测试环境发现。


二、编程建议

在Java开发过程中,最好严格区分原始类型(long/int/short/...)和封装类型(Long/Integer/Short...),虽然JDK能够在大多数情况下进行智能的转型,但是当面对开发一个涉及到金钱的项目时,这样的风险仍然太大!

Java在数据封装类型的设计中,都带了.equals()方法。


三、模拟

1、程序1

public class A {
    public static void main(String[] args) {
        Long l1 = 128L;
        Long l2 = 128L;
        System.out.println(l1 == l2); 
    }
}

程序输出:false

2、程序2

public class A {
    public static void main(String[] args) {
        Long l1 = 127L;
        Long l2 = 127L;
        System.out.println(l1 == l2); 
    }
}

程序输出:true


三、关于LongCache.class

在Long的源代码中,可以找到LongCache内部类的代码:

private static class LongCache {
        private LongCache(){}

        static final Long cache[] = new Long[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }

从LongCache的代码可以很容易看出来,在类初始化的时候,便生成了一个final的static的Long类型数组,数组的范围是-128到127。

Long类型的valueOf方法代码如下:

public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }
从以上两个代码中不难发现,当外部程序调用了valueOf方法时,Java先判断欲生成的Long对象是否在LongCache.cache数组的范围内,如果是,则直接返回已经存在cache数组的Long对象引用。根据之前对String类型的研究,这应该是通过重复使用对象的引用,从而实现了较高的性能和较少的内存消耗。此外,经过测试,通过“Long = long”方式生成的Long对象,称为自动封箱,也有相同的逻辑。
所以也就不难知道,当实际的long大小超过正数127时,判断两个封装类==时,会返回false。

另外一种情况,通过new方式生成的两个等值的对象,是否会有相同的效果呢?经过测试,是否定的。两次new出来的对象,都是在内存中新划分区域生成的对象,除非重写方法,否则是绝对不能通过==进行比较的。



四、其他内容

1、Integer、Short、Character、Bytes等封装类也有类似的机制;

2、请关注JVM参数:AutoBoxCacheMax

3、请关注Integer内部类IntegerCache的high属性。






关于-128到127之间Integer与Long两种类型的比较 public class Test { public static void main(String[] args) { Long a1 = 128L; Long a2 = 128L; System.out.print("a1==a2:"); System.out.println(a1==a2); System.out.print("a1==128L:"); Sy... 阅读详情

相关推荐

从零到一:AnythingLLM与Ollama的本地知识库搭建实战

本文详细介绍了如何使用AnythingLLM与Ollama从零开始搭建本地知识库,涵盖技术选型、环境部署、系统配置及优化策略。通过RAG技术架构,实现安全高效的文档管理与智能问答,特别适合企业及个人构建私有化知识管理系统。

weixin_29079643的博客 562

Java的Long类型缓存机制

LongCache中维护了一个Long类型的数组,用于缓存Long对象,其中数组的大小默认为256(也就是-128到127的范围),如果程序需要使用一个Long对象,Java会首先检查这个Long对象是否在缓存中,如果在,则直接返回缓存中的对象,如果不在,则新建一个Long对象并将其添加到缓存中。具体来说,Java将Long对象缓存的范围定在-128到127之间,也就是说,如果程序中需要使用这个范围内的Long对象,Java会直接返回缓存中的对象,而不是新建一个Long对象。

qq_44993593的博客 973

Tribon Vitesse开发教程(一)

Tribon Vitesse简介 Tribon Vitesse是Tribon提供给Python编程语言的编程接口,它是一系列的API。使用Python的语法调用这些API,结合Python语言自身的语法生成的程序叫做Vitesse程序。Vitesse是法语“速度”的意思,读作“为戴斯”。使用Tribon Vitesse可以直接访问Tribon产品信息模型和使用Tribon应用程序的功能,以控制设计

forevermemory的专栏 2593

IntegerCache、longCache缓存策略与String.intern()用法说明

一道经典面试题: public class Main { private Integer a = 123; private Integer b = 128; private Long c = 123L; private Long d = 1000L; String str = "abc"; public static void main(String[] args) { Mai...

你好,我是橙序员 392

Crawl4AI实战:5分钟搞定电商价格监控爬虫(附Python代码)

本文详细介绍了如何利用开源AI网络爬虫框架Crawl4AI快速构建电商价格监控系统。通过Python实战代码,展示了从环境配置、智能内容提取到多平台适配、定时任务与数据可视化的完整流程,帮助运营人员和技术开发者高效实现自动化价格追踪与竞品分析。

weixin_29090917的博客 414

支付逻辑漏洞的八大姿势(上篇)

学习支付漏洞,看这篇文章!!!文章来源:SecHub网络安全社区(本资料仅供学习参考,严禁使用者进行未授权渗透测试!严禁任何形式的转载!

qq_39493066的博客 1358

Java中的long类型和Long类型比较大小

Java中Long和long的区别 Java的数据类型分为两种: **1、基本类型: byte(8),short(16),int(32),long(64),float(32),double(64),char(16),boolean(1) 2、对象类型: Byte,Short,Integer,Long,Float,Double,Character,Boolean 上面的对象类型分别是基本类型的包装类,例如Byte是byte的包装类. Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象

weixin_42029738的博客 1万+

储能电站 BMS 与车载动力电池 BMS 核心差异:工况、保护策略、控制逻辑对比

储能电站BMS与车载动力电池BMS虽同名,实为针对不同赛道量身定制的产品。简单地将车载BMS方案套用于储能,或将储能BMS思路用于车载,都可能带来性能、安全或成本上的严重问题。在选择和设计BMS时,必须回归其应用场景的本质需求储能BMS是**“资产管理者”**,精打细算,追求在长达十余年的服役期内稳定、高效地创造收益。车载BMS是**“性能与安全卫士”**,反应敏捷,确保在车辆全生命周期内动力澎湃且万无一失。

小帽子的博客 423

java源码阅读之小数缓存

在谈小数缓存之前,我们先来看看这两行代码有什么区别: Long a = new Long(1L); Long b = Long.valueOf(1L); 要区分他们有什么区别,免不了要去看看java源码了。这里我以JDK1.8.0_151的源码做解析: 先看Long的构造函数: private final long value; public Long(long value) { ...

guohengcook的博客 326

Wiley:International Journal for Numerical Methods in Biomedical Engineering投稿流程

中间过程省略,这个出版社很人性化,投稿的web UI也很好看。上传word之后,一步步跟着走就行,不用填太多东西。不要最后在最后检查阶段,重新上传word文件,这样会导致,之前针对word的操作全部改变。

Everyday try to become better -Kobe Bryant 2545

AutosarMCAL开发——基于EB CRC驱动

本文为博主个人理解总结记录,如有不正,欢迎指正。

qq_45583706的博客 1390

LongCache机制与Long等值比较\\\\Integer 中的缓存类IntegerCache

转载自https://www.cnblogs.com/wellmaxwang/p/4422855.htmlhttps://blog.youkuaiyun.com/louistech/article/details/51062966一、背景引入近期在开发一个项目的后台时,当项目上线后出现了一个测试环境没有出现的问题:部分用户在提交信息时提示了该信息不属于当前用户。经过对代码的review,发现了出错的代码的开发...

dayformyjob 1097

SCADA|用KingSCADA实现设备台账的查询功能

以上为用KingSCADA实现设备台账的查询功能,另外还有一些细节功能,比如当点击增加按钮时弹出的信息窗口内的信息希望是在选中的某行信息,只要找到差不多的设备,修改个别参数即可,避免增加时弹出空白页,所有信息都需要填写。以上为实现设备台账查询的最简单实现,实际项目中可能会更复杂,你做过哪些设备台账或相关的功能,有比较好的创意或高难度功能方法,欢迎在留言区评论,或在交流群探讨,互通有无,共同进步。首先完成界面的组态工作,主要是通过查询按钮,查询SQLServer数据库的设备台账数据,然后填充到报表内。

做有价值的事,积累有价值的笔记! 480

深入学习java源码之Long.valueOf()与Long.doubleValue()

深入学习java源码之Long.valueOf()与Long.doubleValue()  在Long的源代码中,可以找到LongCache内部类的代码: private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) +...

悦分享 2219

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

java cacheutil_Java 常用缓存Cache机制的实现

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。缓存主要可分为二大类:一、通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式;二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查.代码如下 :packagelhm.hc...

weixin_29213827的博客 430

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

JAVA常量池,LongCache(-128~127)

private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) ...

一杯星空一个世界的博客 2131

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Java中Long缓存

Long 最被我们关注的就是 Long 的缓存问题,Long 自己实现了一种缓存机制,缓存了从 -128 到 127 内的所有 Long 值,如果是这个范围内的 Long 值,就不会初始化,而是从缓存中拿,缓存 初始化源码如下: private static class LongCache { private LongCache(){} // 缓存,范围从-128到127,+1是因为有个0 static final Long cache[] = new Long[-(-128)

android_jackzhou的博客 1567

Java中常用缓存Cache机制的实现

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33919950的博客 799

java java.lang.Long详解之二 缓存

文章看过后感觉受益匪浅,所以留下了以备温故:http://www.congmo.net/blog/2012/03/05/Long-toString/ 众所周知Long中有个小小的陷阱,就是在-128至127范围内,Long.valueOf(long l)返回的Long的实例是相同的,而在此范围之外每次使用valueOf(long l)时,返回的实例都是不同的。本篇文章的主要目的就是揭示这个小

3230

Java8种基本数据类型的封装,Cache

今天笔试中java题: (1) public static void main (String []args) { Integer a  = new Integer(1); Integer b  = new Integer(1); int c  = 1; Integer e = 1; System.out.println("a==b:"+(a==b)); System.out.p

long636的专栏 1191

Long类型数据比较

之所以记录是因为在开发过程当中,碰到了两次因为个人原因Long类型判断出错导致的bug,因此在此关于Long类型数据比较做一个记录。 注意:long类型和Long类型是不一样,long类型属于基本的数据类型,而Long是long类型的包装类,至于区别是什么再次不做过多详细的解释。 1. 首先说==和equals()方法的区别: ==号在比较基本数据类型,比如int作比较的时候比较的是值。而当...

柚子的博客 3万+

[Java开发之路](19)Long缓存问题

Long中有个小小的陷阱,就是在-128至127范围内,Long.valueOf(long l)返回的Long的实例是相同的,而在此范围之外每次使用valueOf(long l)时,返回的实例都是不同的。 举例: System.out.println(Long.valueOf(-129) == Long.valueOf(-129)); // falseSystem.out.

SmartSi 3492

JAVA中Long与Integer比较容易犯的错误

JAVA中Long与Integer比较容易犯的错误

is_zhoufeng的专栏 6万+

Java 中常用缓存Cache机制的实现

Java 中常用缓存Cache机制的实现 所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。 所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。 缓存主要可分为二大类:  一、通过文件缓存,顾名思...

Fighting_xr的博客 2万+

IntegerCache ByteCache CharacterCache LongCache ShortCache

new Integer(1) 与 Integer.valueOf(1) 的区别 使用Integer.valueOf(1)可以使用系统缓存,既减少可能的内存占用,也省去了频繁创建对象的开销。 public static Integer valueOf(int i) { assert ...

chiyantuo9157的博客 299

Integer&IntegerCache,Long&LongCache

java中 Integer a = 1 实质在编译器中是通过 Integer a = Integer.valueOf(1) 来实现装箱的,a == 1的比较是通过Integer.intValue()来实现拆箱的。那么先看一下第一个方法的源码。 /** * Returns an {@code...

chidanxiao5495的博客 201
上一篇: #测试相关#Getting “junit.framework.AssertionFailedError: Forked Java VM exited abnormally” Exception
下一篇: final关键字与Java编译器的小坑
louis9212
博客等级 码龄14年 8粉丝 49原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值