为什么Java中1000==1000为false而100==100为true?

原文:Why 1000 == 1000 Returns False, but 100 == 100 Returns True in Java? 作者:Bazlur Rahman 译文:http://www.codeceo.com/article/why-java-1000-100.html 译者:码农网-小峰

这是一个挺有意思的讨论话题。

如果你运行下面的代码:

Integer a = 1000, b = 1000; System.out.println(a == b);//1 Integer c = 100, d = 100; System.out.println(c == d);//2

你会得到:

false true

基本知识:我们知道,如果两个引用指向同一个对象,用==表示它们是相等的。如果两个引用指向不同的对象,用==表示它们是不相等的,即使它们的内容相同。

因此,后面一条语句也应该是false 。

这就是它有趣的地方了。如果你看去看 Integer.java 类,你会发现有一个内部私有类,IntegerCache.java,它缓存了从-128到127之间的所有的整数对象。

所以事情就成了,所有的小整数在内部缓存,然后当我们声明类似——

Integer c = 100;

的时候,它实际上在内部做的是:

Integer i = Integer.valueOf(100);

现在,如果我们去看valueOf()方法,我们可以看到

public static Integer valueOf(int i) { if (i >= IntegerCache.low && i return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }

如果值的范围在-128到127之间,它就从高速缓存返回实例。

所以…

Integer c = 100, d = 100;

指向了同一个对象。

这就是为什么我们写

System.out.println(c == d);

我们可以得到true。

现在你可能会问,为什么这里需要缓存?

合乎逻辑的理由是,在此范围内的“小”整数使用率比大整数要高,因此,使用相同的底层对象是有价值的,可以减少潜在的内存占用。

然而,通过反射API你会误用此功能。

运行下面的代码,享受它的魅力吧

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { Class cache = Integer.class.getDeclaredClasses()[0]; //1 Field myCache = cache.getDeclaredField("cache"); //2 myCache.setAccessible(true);//3 Integer[] newCache = (Integer[]) myCache.get(cache); //4 newCache[132] = newCache[133]; //5 int a = 2; int b = a + a; System.out.printf("%d + %d = %d", a, a, b); // }

—————END—————

看完本文有意思?请分享给更多人

小伙伴们,你怎么看!

原文发布于微信公众号 - 顶级程序员(TopCoding)

原文发表时间:2017-03-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个会写诗的程序员的博客

第7章 面向对象编程(OOP)

7.2 类与继承 7.2.1 类 7.2.1.1 抽象类 7.2.1.2 接口 7.2.1.3 枚举 7.2.1.4 注解 7.2.1.5 静态类与...

651
来自专栏IT笔记

Java基础精选,你答对了几道?

没有技术深度是大多程序员的一种常态。 但是当你成为一个资深的工程师的时候,很多公司并不希望你还是那样平庸,没有深度。虽然你会纳闷,我就算有深度你们也不一定用得上...

2705
来自专栏贺贺的前端工程师之路

《JavaScript语言精粹》学习笔记

在JavaScript中,/ *可能出现在正则表达式字面量里,所以块注释对于被注释的代码块来说是<u>不安全的</u>。

782
来自专栏take time, save time

初级程序员面试不靠谱指南(六)

五.很强很伟大的函数指针     我想看到这个标题中“函数指针”几个字之后,估计有一半人会选择关掉界面,因为我最开始学习C语言的时候这一章我曾无数次跳过,看到书...

34910
来自专栏一个会写诗的程序员的博客

第6章 类型系统

6.3 基本类型(Primitive Types) 6.3.1 Number: 包含整型与浮点型等 6.3.2 Char: 字符类型(Character) ...

1083
来自专栏菜鸟前端工程师

JavaScript学习笔记016-字符串方法0数组方法0值类型与引用型

822
来自专栏C语言C++游戏编程

C语言编程中复杂的循环结构,你被循环晕了吗?

当一段代码需要执行多次时,您可能会遇到这种情况。通常,语句按顺序执行:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。

1372
来自专栏进击的君君的前端之路

Math对象、数组、日期函数

1625
来自专栏信数据得永生

JavaScript 编程精解 中文第三版 一、值,类型和运算符

3668
来自专栏Java帮帮-微信公众号-技术文章全总结

【Java提高四】接口与抽象类

【Java提高四】接口与抽象类 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。 抽象类与接口是java语言中对抽象概念进行定义的...

3756

扫码关注云+社区

领取腾讯云代金券