如何向女友解释int==Integer为true

int==Integer为何返回true

先看现象吧java

执行下面的代码及输出结果:bash

int a = 1;
Integer b = 1;
Integer c = new Integer(1);
System.out.println(a==b);//true
System.out.println(a==c);//true
System.out.println(b==c);//false
复制代码

一般你们对此的解释是,==对于基本类型来讲比较的是值,对于引用类型来讲比较的是引用,即指向的对象的内存地址。这样解释没错,b==c结果为false毋庸置疑,由于两个都是引用类型。可是为何a==b(a==c)一个是基本类型一个是引用类型,比较的时候仍是值比较呢?网络

这个时候咱们不妨把.java源文件编译后的.class文件使用反编译工具反编译成源码,看看虚拟机内部是如何处理a==b的。工具

.class文件使用jd-gui反编译后的:ui

int a = 1;
Integer b = Integer.valueOf(1);
Integer c = new Integer(1);
System.out.println(a == b.intValue());
System.out.println(a == c.intValue());
System.out.println(b == c);
复制代码

看到这想必你们都明白了吧,其实基本类型a和引用类型b比较时,引用类型b调用自身的intValue()方法获取Integer实际表示的int类型的值,即a == b.intValue()仍是两个int类型的变量进行值比较。符合上述:==对于基本类型来讲比较的是值,对于引用类型来讲比较的是引用,即指向的对象的内存地址。spa

基本类型及引用类型在内存中的存储方式

说到这,还要解释下为何两个引用类型的值同样而引用不同以及基本变量为何是值比较。code

其实基本变量int a在内存里只有一份,保存在栈(保存基本类型的变量数据及引用类型的引用)中,Integer b和Integer c中的int值都指向栈中同一个int,不会从新在栈中建立相同的int值。cdn

而对于Integer b和Integer c,其实例是保存在堆(保存全部new出来的对象)中,虽然表示的int值相同,可是在堆中有两份,每次new都会在堆中开辟一片空间保存new的内容,故Integer b和Integer c分别在两片不一样的内存空间存储,因此指向的内存地址不一样。对象

而对于Integer b = 1;其反编译后为Integer b = Integer.valueOf(1); 而valueOf()方法内部是调用了new。

JDK中Integer.valueOf()源码:blog

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

总结

了解原理是弄清问题的关键,像这样的问题之后还多着呢。不懂的时候能够敲敲代码,而后反编译,看看虚拟机是怎么处理的,看看原理翻翻源码,问题也就迎刃而解了。


(封面图片来源于网络,侵权请联系删除)

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息