从字节码的层面来解释一下为什么Integer a=128,Integer b=128,a==b是false

先来看一下这么一段代码:

public class IntegerMain {
    public static void main(String[] args) {
        Integer a = 127;
        Integer b = 127;
        System.err.println(a == b);
        System.err.println("======================");
        Integer c = 128;
        Integer d = 128;
        System.err.println(c == d);
    }

}

对于广大的Java程序员来说,这一段代码再熟悉不过,不知道曾经面试被问到多少回,我就曾经面试过五年以上的都答不上来,更说不上来原因,当然从实际工作角度来看,这个题目没什么意义,但是这个世界时残酷的,没有意义不代表你可以不学,就好比我们大多数人上大学一样,学校教的东西有用的并不多,好了,不扯了,说正事儿,上面那段代码,大家都知道第一个判断是输出true,第二个判断是输出false,我也相信很多人都知道这个是因为Integer内部初始化了一个缓存数组,数组里面默认存的是-128到正的127,所以在这个范围内直接用双等号是可以达到预期的效果的,但是从java代码层面是看不出来为什么会用到缓存的,这就需要从字节码层面来解释了,如下是这段代码的字节:

 0 bipush 127
 2 invokestatic #2 <java/lang/Integer.valueOf>
 5 astore_1
 6 bipush 127
 8 invokestatic #2 <java/lang/Integer.valueOf>
11 astore_2
12 getstatic #3 <java/lang/System.err>
15 aload_1
16 aload_2
17 if_acmpne 24 (+7)
20 iconst_1
21 goto 25 (+4)
24 iconst_0
25 invokevirtual #4 <java/io/PrintStream.println>
28 getstatic #3 <java/lang/System.err>
31 ldc #5 <======================>
33 invokevirtual #6 <java/io/PrintStream.println>
36 sipush 128
39 invokestatic #2 <java/lang/Integer.valueOf>
42 astore_3
43 sipush 128
46 invokestatic #2 <java/lang/Integer.valueOf>
49 astore 4
51 getstatic #3 <java/lang/System.err>
54 aload_3
55 aload 4
57 if_acmpne 64 (+7)
60 iconst_1
61 goto 65 (+4)
64 iconst_0
65 invokevirtual #4 <java/io/PrintStream.println>
68 return

看不懂不要紧,我们重点第一行和第二行:

 0 bipush 127
 2 invokestatic #2 <java/lang/Integer.valueOf>

这个对应的也就是代码里面的Integer a=127;

那么现在大家应该知道了Integer a=127;实际上调用的是Integer类的valueOf方法,我们看这个方法的实现:

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

这段代码的意思就是先从Integer.cache里面去找,找到了就返回,找不到就new 一个Integer的类型,那么现在就清楚了为什么最前面的代码里面a和b是双等号是true,c和d双等号是false了,为了验证这个结论,我们可以改一改代码:

public class IntegerMain {
    public static void main(String[] args) {
        Integer a = 127;
        Integer b = 127;
        System.err.println(a == b);
        System.err.println("======================");
        Integer c = 128;
        Integer d = 128;
        System.err.println(c == d);
        System.err.println("======================");
        Integer e = 127;
        Integer f = Integer.valueOf(127);
        System.err.println(e == f);
    }
}

运行结果:

猜你喜欢

转载自blog.csdn.net/qq_17805707/article/details/132108413