https://blog.csdn.net/magician_Code/article/details/51469101

我们先来看看下面代码的运行情况:

  1. public static void main(String[] args)
  2. {
  3. // TODO Auto-generated method stub
  4. Integer integer1;
  5. Integer integer2;
  6.  
  7. integer1 = new Integer(10);
  8. integer2 = new Integer(10);
  9. //第一次比较
  10. System.out.println("第一次比较:"+(integer1==integer2));
  11.  
  12. //第二次比较
  13. System.out.println("第二次比较:"+(integer1==10));
  14.  
  15. integer1 = 127;
  16. integer2 = 127;
  17. //第三次比较
  18. System.out.println("第三次比较:"+(integer1==integer2));
  19.  
  20. integer1 = 128;
  21. integer2 = 128;
  22. //第四次比较
  23. System.out.println("第四次比较:"+(integer1==integer2));
  24. }

运行程序,结果如下:

你看出了运行结果了吗?

第一次和第二次比较就无可厚非了,第一次是直接把两个不同的对象比较,当然是false;第二次比较时,是把Integer对象和int型10进行比较,根据自动装箱、拆箱机制,这时候的比较就等价于10==10,所以是true。那么后面两个为什么会出现两种不同的结果呢?

首先我们先来看看Integer的两种定义方式:

  1. Integer integer1 = new Integer(10);
  2. Integer integer2 = 10;

第一种是我们常见的创建一个对象的方法,那么第二个方法呢?根据Java的自动装箱、拆箱机制,这时在Integer内部实际上是做了如下操作:

  1. Integer integer2 = Integer.valueOf(10);

这时我们查看Integer源码中关于valueOf方法的定义:

  1. public static Integer valueOf(int paramInt)
  2. {
  3. if ((paramInt >= -128) && (paramInt <= IntegerCache.high)) {
  4. return IntegerCache.cache[(paramInt + 128)];
  5. }
  6. return new Integer(paramInt);
  7. }

这里我们会留意到”IntegerCache”这个类,跟踪一下代码,发现这是Integer的一个私有内部类,声明如下:

  1. private static class IntegerCache
  2. {
  3. static final int low = -128;
  4. static final int high;
  5. static final Integer[] cache;
  6.  
  7. private IntegerCache() {}
  8.  
  9. static
  10. {
  11. int i = 127;
  12. String str = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
  13. if (str != null) {
  14. try
  15. {
  16. int j = Integer.parseInt(str);
  17. j = Math.max(j, 127);
  18. i = Math.min(j, 2147483518);
  19. }
  20. catch (NumberFormatException localNumberFormatException) {}
  21. }
  22. high = i;
  23. cache = new Integer[high - -128 + 1];
  24. int k = -128;
  25. for (int m = 0; m < cache.length; m++) {
  26. cache[m] = new Integer(k++);
  27. }
  28. assert (high >= 127);
  29. }
  30. }
  31. }

这段代码并不难读,这里类缓存了从-128到127之间的所有整型对象,意思是当使用自动装箱的方式定义一个值在-128到127的Integer对象时,我们得到的是从缓存区(IntegerCache)中返回的实例。

所以,当我们在进行上面的第三次比较时,此时的integer1和integer2是同一个对象,那么比较的结果当然是true啦。第四次是因为我们指定的值为128,>127,所以Integer内部会创建新的对象返回,所以当然不可能相等。

最后啰嗦一下,如果要进行两个Integer对象基于数值的比较时,因为Integer实现了Compaeable接口,所以直接使用compaerTo方法进行比较会比较妥当。判等的话还可以使用equals方法,于是我们把最开始的代码改成如下:

  1. public static void main(String[] args)
  2. {
  3. // TODO Auto-generated method stub
  4. Integer integer1;
  5. Integer integer2;
  6.  
  7. integer1 = new Integer(10);
  8. integer2 = new Integer(10);
  9. //第一次比较
  10. //System.out.println("第一次比较:"+(integer1==integer2));
  11. if(integer1.equals(integer2))
  12. System.out.println("第一次比较:"+true);
  13. else
  14. System.out.println("第一次比较:"+false);
  15.  
  16. //第二次比较
  17. System.out.println("第二次比较:"+(integer1==10));
  18.  
  19. integer1 = 127;
  20. integer2 = 127;
  21. //第三次比较
  22. //System.out.println("第三次比较:"+(integer1==integer2));
  23. if(integer1.equals(integer2))
  24. System.out.println("第三次比较:"+true);
  25. else
  26. System.out.println("第三次比较:"+false);
  27.  
  28. integer1 = 128;
  29. integer2 = 128;
  30. //第四次比较
  31. //System.out.println("第四次比较:"+(integer1==integer2));
  32. if(integer1.equals(integer2))
  33. System.out.println("第四次比较:"+true);
  34. else
  35. System.out.println("第四次比较:"+false);
  36. }

Integer判等的陷阱:你知道Integer内部高速缓冲区IntegerCache吗?的更多相关文章

  1. 面试陷阱1:Integer类型的比较

    public class Test01 { public static void main(String[] args) { Integer f1 = 100, f2 = 100, f3 = 150, ...

  2. java Integer判等的大坑

    在-128 至 127 范围内的赋值,Integer 对象是在IntegerCache.cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用==进行 判断,但是这个区间之外的 ...

  3. Microsoft Office Access

    Microsoft Office Access各版本下载地址:http://www.accessoft.com/download.html 简介 access(微软发布的关联式数据库管理系统)一般指M ...

  4. 【转】理解Java Integer的缓存策略

    本文将介绍 Java 中 Integer 缓存的相关知识.这是 Java 5 中引入的一个有助于节省内存.提高性能的特性.首先看一个使用 Integer 的示例代码,展示了 Integer 的缓存行为 ...

  5. 理解Java Integer的缓存策略

    转载自http://www.importnew.com/18884.html 本文将介绍 Java 中 Integer 缓存的相关知识.这是 Java 5 中引入的一个有助于节省内存.提高性能的特性. ...

  6. 【转载】C#之int与Java之Integer的区别

    本文涉及到一些JVM原理和Java的字节码指令,推荐感兴趣的读者阅读一本有关JVM的经典书籍<深入Java虚拟机(第2版)>,将它与我在<.NET 4.0面向对象编程漫谈>中介 ...

  7. Integer封装与拆箱

    Integer封装与拆箱 简介: 目录: Integer自动封装的陷阱 Integer自动拆箱机制 Integer自动封装的陷阱 public class IntegerDemo { public s ...

  8. 理解Java Integer的缓存策略【转】

    本文由 ImportNew - 挖坑的张师傅 翻译自 javapapers.欢迎加入翻译小组.转载请见文末要求. 本文将介绍 Java 中 Integer 缓存的相关知识.这是 Java 5 中引入的 ...

  9. 17_java之Integer|System|Arrays|Math|BigInteger|BigDecimal

    01基本数据类型对象包装类概述 *A:基本数据类型对象包装类概述 *a.基本类型包装类的产生 在实际程序使用中,程序界面上用户输入的数据都是以字符串类型进行存储的.而程序开发中,我们需要把字符串数据, ...

随机推荐

  1. spring学习(二)---依赖注入

    spring第二个特性是依赖注入. 学习依赖注入,首先应该明白两个问题:1,谁依赖谁:2,谁注入,注入什么? 首先还是看代码: 还是这个bean: package testSpring.busines ...

  2. bgfx入门练习3——编译自定义Shader

    马个鸡,总算编译过了自定义Shader,在此感谢自己,感谢自己,以及感谢自己.没有自己的努力,我是不可能解决这个问题的,自己真是太叼了.妈的智障!!! 管方那屎一样的make工具根本没用,反正我是折腾 ...

  3. temp--内蒙农信出差

    ============================2018.09.18~~~20181001================================== -------住宿----黎明花 ...

  4. @RequestParam与@PathVariable

    @PathVariable 带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义 通过 @PathVariable 可以 ...

  5. iBtais 多重嵌套循环

    iBatis支持集合循环, 但是如何做到双重循环, 请见下例子 例子描述: 需要去三张结构相同的表中获取信息, 需要将信息拼合去重后返回 入参数据类型: Map<String,Object> ...

  6. sudo -iu [用户] 命令无法正常切换到用户目录的原因

    今天干活时遇到一个问题,在sudo -iu [用户]命令执行后无法切换到用户对应的[ 用户@机器 ~$ ]命令行 .bashrc已正常配置为 if [ -f /etc/bashrc ]; then . ...

  7. java面试一、1.1基础

    免责声明:     本文内容多来自网络文章,转载为个人收藏,分享知识,如有侵权,请联系博主进行删除. 基础篇 1.1Java基础 面向对象的特征:继承.封装和多态 三大特性是:封装,继承,多态 所谓封 ...

  8. 2019/3/4 java集合学习(二)

    java集合学习(二) 在学完ArrayList 和 LinkedList之后,基本已经掌握了最基本的java常用数据结构,但是为了提高程序的效率,还有很多种特点各异的数据结构等着我们去运用,类如可以 ...

  9. IOS 模拟器多开集成测试和那些坑

    #### 前言公司一直没有IOS自动化,搞得很尴尬,个人感觉搞自动测试的,不搞IOS自动化,就像金X,少了重要一点啊.也向领导申请过不止一次,总只都各种原因没有分配机器,不了了之.某天线上IOS出bu ...

  10. js-图片轮播(极简)

    <!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" ...