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

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

public static void main(String[] args)
{
// TODO Auto-generated method stub
Integer integer1;
Integer integer2; integer1 = new Integer(10);
integer2 = new Integer(10);
//第一次比较
System.out.println("第一次比较:"+(integer1==integer2)); //第二次比较
System.out.println("第二次比较:"+(integer1==10)); integer1 = 127;
integer2 = 127;
//第三次比较
System.out.println("第三次比较:"+(integer1==integer2)); integer1 = 128;
integer2 = 128;
//第四次比较
System.out.println("第四次比较:"+(integer1==integer2));
}

运行程序,结果如下:

你看出了运行结果了吗?

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

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

Integer integer1 = new Integer(10);
Integer integer2 = 10;

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

Integer integer2 = Integer.valueOf(10);

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

public static Integer valueOf(int paramInt)
{
if ((paramInt >= -128) && (paramInt <= IntegerCache.high)) {
return IntegerCache.cache[(paramInt + 128)];
}
return new Integer(paramInt);
}

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

private static class IntegerCache
{
static final int low = -128;
static final int high;
static final Integer[] cache; private IntegerCache() {} static
{
int i = 127;
String str = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (str != null) {
try
{
int j = Integer.parseInt(str);
j = Math.max(j, 127);
i = Math.min(j, 2147483518);
}
catch (NumberFormatException localNumberFormatException) {}
}
high = i;
cache = new Integer[high - -128 + 1];
int k = -128;
for (int m = 0; m < cache.length; m++) {
cache[m] = new Integer(k++);
}
assert (high >= 127);
}
}
}

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

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

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

public static void main(String[] args)
{
// TODO Auto-generated method stub
Integer integer1;
Integer integer2; integer1 = new Integer(10);
integer2 = new Integer(10);
//第一次比较
//System.out.println("第一次比较:"+(integer1==integer2));
if(integer1.equals(integer2))
System.out.println("第一次比较:"+true);
else
System.out.println("第一次比较:"+false); //第二次比较
System.out.println("第二次比较:"+(integer1==10)); integer1 = 127;
integer2 = 127;
//第三次比较
//System.out.println("第三次比较:"+(integer1==integer2));
if(integer1.equals(integer2))
System.out.println("第三次比较:"+true);
else
System.out.println("第三次比较:"+false); integer1 = 128;
integer2 = 128;
//第四次比较
//System.out.println("第四次比较:"+(integer1==integer2));
if(integer1.equals(integer2))
System.out.println("第四次比较:"+true);
else
System.out.println("第四次比较:"+false);
}

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. 2019.03.28 bzoj3325: [Scoi2013]密码(manacher+模拟)

    传送门 题意: 现在有一个nnn个小写字母组成的字符串sss. 然后给你nnn个数aia_iai​,aia_iai​表示以sis_isi​为中心的最长回文串串长. 再给你n−1n-1n−1个数bib_ ...

  2. 移动端布局:视口viewport的理解

    移动端开发中,有一些基本概念需要理解清楚,才能更好的组织编程逻辑.在刚接触时,移动端视口的缩放和rem单位的缩放搞混淆了,弄得自己很蒙圈.所以仔细总结下自己的理解. 移动端的适配,我理解为两点: 第一 ...

  3. js 颜色选择插件

    COLPICK是一款非常的轻小,无需图片就可以实现颜色选择器的jquery插件,只用 JS 和 CSS 就实现了全部功能,而且非常直观,类似Photoshop的界面,使用方便.颜色的明暗很容易自定义, ...

  4. Java 异常与反射 总结

    1.异常 异常,简单来说,就是一个程序执行过程中发生的不正常情况的事件.它发生在程序的运行期间,干扰了正常的指令流程.如果没有处理异常,那么出现异常之后,程序会停止运行.异常分为运行异常和非运行异常. ...

  5. SQL给数据编号

    方法:ROW_NUMBER() over(order by getdate()) AS num 使用案例 : select * From (select  ROW_NUMBER() over(orde ...

  6. XML学习总结二——DTD

    主要用处是约束XML. 1.DTD分为内部DTD与外部DTD两类: 内部DTD:将DTD定义在XML文档的内部 <!DOCTYPE  根元素名  [    元素描述]> 外部DTD < ...

  7. DOM1级问题与DOM2级事件

    前几天有小伙伴问过我一个问题,为什么有DOM 0级事件以及DOM2级事件,但是却没有DOM1级事件呢?那我们今天就来说一说DOM的级别问题. 同时推荐伙伴们可以看看尚学堂有关JavaScript BO ...

  8. Android JNI 学习(六):Object Operations Api

    一.AllocObject jobjectAllocObject(JNIEnv *env, jclass clazz); 分配新 Java 对象而不调用该对象的任何构造函数.返回该对象的引用. cla ...

  9. Webview 浏览器开源项目总结

    在Android开发中,我们不免会遇到使用WebView实现网页展示的需求,以下是本人之前star的开源项目,供大家参考: 一.CrosswalkWebview 项目地址:https://github ...

  10. 安装owncloud作为自己的云服务器

    环境:centos7,php5.6.37,apache2.4.6 首先,环境都要搭好,与之前搭wordpress网站是一样的.接下来下载程序 wget https://download.ownclou ...