浅谈为什么Java中1000==1000为false而100==100为true

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

如果你运行下面的代码

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); //
  }

英文原文:Why 1000 == 1000 Returns False, but 100 == 100 Returns True in Java?

到此这篇关于浅谈为什么Java中1000==1000为false而100==100为true的文章就介绍到这了,更多相关Java 1000==1000为false 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java 中 request.getSession(true、false、null)的区别

    java 中 request.getSession(true/false/null)的区别 一.需求原因 现实中我们经常会遇到以下3中用法: HttpSession session = request.getSession(); HttpSession session = request.getSession(true); HttpSession session = request.getSession(false); 二.区别 1.      Servlet官方文档说: public Http

  • 浅谈为什么Java中1000==1000为false而100==100为true

    这是一个挺有意思的讨论话题. 如果你运行下面的代码 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

  • 浅谈在Java中使用Callable、Future进行并行编程

    使用Callable.Future进行并行编程 在Java中进行并行编程最常用的方式是继承Thread类或者实现Runnable接口.这两种方式的缺点是在任务完成后无法直接获取执行结果,必须通过共享变量或线程间通信,使用起来很不方便. 从Java1.5开始提供了Callable和Future两个接口,通过使用它们可以在任务执行完毕后得到执行结果. 下面我们来学习下如何使用Callable.Future和FutureTask. Callable接口 Callable接口位于java.util.co

  • 浅谈从Java中的栈和堆,进而衍生到值传递

    简述Java中的栈和堆,变量和对象的地址存放和绑定机制 初学java的小白,很多人都搞不清楚java中堆和栈的概念,我们都知道计算机只能识别二进制字节码文件,如果分不清楚对象和变量在内存的地址分配,也就是堆和栈的问题,很多问题比如绑定机制.静态方法.实例方法.局部变量的作用域就会搞不清楚. 首先记住结论: 基本数据类型.局部变量.String类型的直接赋值都是存放在栈内存中的,用完就消失. new创建的实例化对象.String类型的构造方法new出来的对象及数组,是存放在堆内存中的,用完之后靠垃

  • 浅谈在Java中JSON的多种使用方式

    1. 常用的JSON转换 JSONObject 转 JSON 字符串 JSONObject json = new JSONObject(); jsonObject.put("name", "test"); String str = JSONObject.toJSONString(json); JSON字符串转JSON String str = "{\"name\":\"test\"}"; JSONObjec

  • 浅谈对java中锁的理解

    在并发编程中,经常遇到多个线程访问同一个 共享资源 ,这时候作为开发者必须考虑如何维护数据一致性,在java中synchronized关键字被常用于维护数据一致性.synchronized机制是给共享资源上锁,只有拿到锁的线程才可以访问共享资源,这样就可以强制使得对共享资源的访问都是顺序的,因为对于共享资源属性访问是必要也是必须的,下文会有具体示例演示. 一.java中的锁 一般在java中所说的锁就是指的内置锁,每个java对象都可以作为一个实现同步的锁,虽然说在java中一切皆对象, 但是锁

  • java web学习_浅谈request对象中get和post的差异

    阅读目录(Content) •1.get与post的区别 •1.1 get方法 jsp中的代码form表单代码 •1.2 action包中servlet的doGet方法中的代码 •2.运行结果 •2.1 输入数据 •2.2 打印出数据 •3.post方法 •4.对比 •4.1 在输出页面按下F12查看 •5.分析 1.get与post的区别 Get和Post方法都是对服务器的请求方式,只是他们传输表单的方式不一样. 下面我们就以传输一个表单的数据为例,来分析get与Post的区别 1.1 get

  • 浅谈在JAVA项目中LOG4J的使用

    一.直接使用: //输出到项目文件夹下output1.txt文件中 ////////////////////////////// // DEBUG - Here is some DEBUG // INFO - Here is some INFO // WARN - Here is some WARN // ERROR - Here is some ERROR // FATAL - Here is some FATAL ////////////////////////////// package

  • 浅谈springboot项目中定时任务如何优雅退出

    在一个springboot项目中需要跑定时任务处理批数据时,突然有个Kill命令或者一个Ctrl+C的命令,此时我们需要当批数据处理完毕后才允许定时任务关闭,也就是当定时任务结束时才允许Kill命令生效. 启动类 启动类上我们获取到相应的上下文,捕捉相应命令.在这里插入代码片 @SpringBootApplication /**指定mapper对应包的路径*/ @MapperScan("com.youlanw.kz.dao") /**开启计划任务*/ @EnableScheduling

  • 浅谈PHP正则中的捕获组与非捕获组

    今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可行的,于是总结一下,分享的同时也希望有大神和细心的学习者找到我理解中出现的问题. 什么是捕获组 我们先看一下PHP的正则匹配函数 int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags =

  • 浅谈MySQL存储过程中declare和set定义变量的区别

    在存储过程中常看到declare定义的变量和@set定义的变量.简单的来说,declare定义的类似是局部变量,@set定义的类似全局变量. 1.declare定义的变量类似java类中的局部变量,仅在类中生效.即只在存储过程中的begin和end之间生效. 2.@set定义的变量,叫做会话变量,也叫用户定义变量,在整个会话中都起作用(比如某个应用的一个连接过程中),即这个变量可以在被调用的存储过程或者代码之间共享数据.如何理解呢?可以看下面这个简单例子,很好理解. (1)先执行下面脚本,创建一

随机推荐