Integer的 128至127 - wtstengshen/blog-page GitHub Wiki

#Integer的-128至127 上来先看一个老掉牙的面试题经常搞的,程序

    public static void main(String[] args) {

		int i = 127;  // (1)
		Integer j = 127; // (2)
		Integer k = new Integer(127); // (3)
		
		System.out.println(i == j); // (4)
		System.out.println(i == k); // (5)
		System.out.println(j == k); // (6)
	}

其实这边文章的中点不是说这个题目的执行结果是什么,而是分析一下源码,看一下class长什么样子,合理的结合源码分析程序执行的结果,知其然,比知其所以然。

1,为什么会有人考上边的题目,而且都是Integer,为啥不是Double

为什么偏偏是127? 默认jvm的配置都不改的情况下,结果是 true,true,false 其实分析问题的关键在于在编译的时候上边这段程序都干了什么事情,我们可以使用eclipse的插件ByteCode查看一下程序编译后张什么样子,我在重要的部分添加了数字,我只保留了重要的部分,自己可以下载查看看一下,这个插件带有联动效果

  L1
    LINENUMBER 8 L1
    BIPUSH 127
    
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;// (重点2)
    ASTORE 2
    
    ILOAD 1
    ALOAD 2
    INVOKEVIRTUAL java/lang/Integer.intValue ()I  // (重点4)
    IF_ICMPNE L4
    ICONST_1
    
     LINENUMBER 12 L6
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ILOAD 1
    ALOAD 3
    INVOKEVIRTUAL java/lang/Integer.intValue ()I  // (重点5)
    IF_ICMPNE L7
    ICONST_1

分析一下

	Integer j = 127; // (2)

这句代码编译之后,是在(重点2)的地方,你会发现这行代码实际的执行代码是

    Integer j = Integer.valueOf(127);

然后我们分析一下Integer.valueOf 都做了什么事情,查看jdk的源码,你会发现如下的代码:

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

你会发现返回值不是new Integer,而是从IntegerCache中返回我们需要的对象。 代码中 注释4的地方,对应的编译后的代码是:

 INVOKEVIRTUAL java/lang/Integer.intValue ()I  // (重点4)

其实在比较大小的时候,调用了Integer.intValue方法,然后在比较大小,所以,前两个为什么都是true也就明亮了,虽然比较大小一个是基本类型,一个是包装类型,但是调用了包装类型的intValue方法,这也就是所谓的拆箱。 最后一个比较大小因为是两个不同的Integer对象,所以是false;