再谈包装类Integer对象的比较

public class CompareDemo {

    public static void main(String[] args) {
        int a = 128, b = 128;
        System.out.println(a == b); // true

        Integer c = 128, d = 128;
        System.out.println(c == d); // false

        System.out.println(c.equals(d)); // true

        Integer e = -128, f = -128;
        System.out.println(e == f); // true
    }
}

我们在命令行执行一下

1. javac CompareDemo.java

2. javap -c CompareDemo

部分截图如下:

可以看到在 在执行 Integer c = 128, d = 128; 时调用了两次 Integer.valueOf()函数。

所以语句  Integer c = 128 ; 等同于 Integer c = Integer.valueOf(128);

Integer d = 128 ; 等同于 Integer d = Integer.valueOf(128);

我们从源码中看下这个函数的实现:

public static Integer valueOf(int i) {
    final int offset = 128;
    if (i >= -128 && i <= 127) { // must cache
        return IntegerCache.cache[i + offset];
    }
        return new Integer(i);
    }

很明显当i >= -128 且 i <= 127 时,我们返回的是缓存中的Integer的对象。

内部类 IntegerCache 定义如下:

private static class IntegerCache {
    private IntegerCache(){}

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

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

这就解释了为什么 c == d 返回的为什么是false了, c,d 这里都是对象,== 比较的是引用的地址,

c.equals(d) 才是对象中值的比较。正是因为c,d 的128超出了IntegerCache缓存的范围,所以c,d

是两个不同的对象,自然引用地址也不同。

而e , f 的-128 则在缓存的范围内,故返回的是同一个对象。引用地址相同。

时间: 2024-08-30 09:57:24

再谈包装类Integer对象的比较的相关文章

再谈 Object Factories(对象工厂)

为何而写: 为什么再谈一次,因为上次代码实在是不够好.上篇文章对象工厂给出的代码太过拙劣,限于学识,我自己类型擦除技术仅仅是把对象的指针转换为void* 而已,实际上可以更为巧妙.这次利用新的类型擦出技术,给出一个完美的解决方,请看下文. 前情描述: 我为什么不直接保存用户提供的function的void*而非要把他copy一份利用容器vector储存起来,然后再去取其指针转换为void*.是因为用户传来的function可能是右值或临时值,一个马上要被删除的值,如果我们直接使用用户提供的fun

再谈类和对象

类和对象是Java中的常见概念,类具有四个特点: 对象性,封装性,继承性,多态性. 我学到了同一个类的不同对象是独立的,也学了 this 关键字的用法,还有static 的用法,也练习了 课堂上的程序,最后还学到了构造函数,以及类的 运行图. 也学到了作用域的概念,内部的作用域可以访问外部 的作用域,外部的不能访问内部的同名变量,今天 课堂上的例子代码量加大了一些,很多东西要好好 吸收和多看几次! 原文地址:https://www.cnblogs.com/sjnnjs/p/10742523.ht

【Go语言】【13】再谈GO语言的结构体

本文从如下四个方面再领着大家认识结构体 匿名结构体和匿名成员的结构体 值传递和引用传递 再谈嵌套结构体 面向对象 1.匿名结构体和匿名成员的结构体 如上篇所述,一个结构体需要先声明,再初始化,最后把初始化后的结构体赋值给其它变量,例如: /*声明结构体*/ type employee struct{ name,address string height,weight float64 } /*初始化结构体,并赋给变量emp*/ emp := employee{name:"eagle",

万恶之源-再谈编码

万恶之源-再谈编码 本节主要内容: ?小数据池 is和==的区别 3. 编码的问题 ?一. ?小数据池 在说?小数据池之前. 我们先看?一个概念念. 什什么是代码块: 根据提示我们从官?方?文档找到了了这样的说法: A Python program is constructed from code blocks. A block is a piece of Python program text that is executed as a unit. The following are bloc

C++ Primer 学习笔记_73_面向对象编程 --再谈文本查询示例

面向对象编程 --再谈文本查询示例 引言: 扩展第10.6节的文本查询应用程序,使我们的系统可以支持更复杂的查询. 为了说明问题,将用下面的简单小说来运行查询: Alice Emma has long flowing red hair. Her Daddy says when the wind blows through her hair, it looks almost alive, like a fiery bird in flight. A beautiful fiery bird, he

Java基础——再谈面向对象

去年的这个时候,心血来潮写了篇<简述面向对象技术>,先在看来不由的会想:这都是写的什么跟什么啊?(ps:虽然现在写的博客依然不咋地)但是,Java的学习中又一次不得不再一次面向对象,所以,奉上一篇<再谈面向对象>,做为新年的一盘开胃菜. 面向对象是相对于面向过程而言,是一种思想. 区别于面向过程: 面向过程是以函数为基础,完成各种操作,强调的是过程,而面向对象是以对象为基础,强调的是对象. 比如说把大象装进冰箱分为几步,宋丹丹是这样说的:三步呗, 第一步:打开冰箱门, 第二步:把大

Another Look at Events(再谈Events)

转载:http://www.qtcn.org/bbs/simple/?t31383.html Another Look at Events(再谈Events) 最近在学习Qt事件处理的时候发现一篇很不错的文章,是2004年季刊的一篇文章,网上有这篇文章的翻译版,但是感觉部分地方翻译的比较粗糙,不是很明确.索性重新翻译了一遍,并引用了原翻译版的一段译注.以下都是用自己能理解的方式来翻译的,由于水平有限,有很多不足的地方,希望大家指正. Another Look at Events (再谈Event

JAVA中Integer对象的引用

JAVA中没有指针一说,但也有引用的概念.这里要说的主要是Integer是不是同一个对象. 1.先看一段代码: public static void main(String[] args){ Integer a1 = 100; Integer b1 = a1;//另一种也可以b1=100 Field field = null; try { field = a1.getClass().getDeclaredField("value"); } catch (NoSuchFieldExcep

OpenglES2.0 for Android:再谈纹理映射

OpenglES2.0 for Android:再谈纹理映射 前言 上一节我们实现了一个简单的纹理映射的例子--一个简单的贴图,这节我们来做一些稍微复杂一点的例子,最后再给我们前面的立方体做一个纹理. 纹理拉伸 重复拉伸方式 这种是经常使用的一张纹理拉伸方式,常用于绘制一些重复的元素,比如我们在游戏绘制一幅方格式的地图时.使用重复拉伸方式使得纹理能够根据目标平 面的大小自动重复,这样既不会失去纹理图的效果,也可以节省内存.如下图所示: 实现起来很简单,我们回到上节的项目,找到我们纹理的工具类Te