关于 new integer 和integer.valueOf() 和 int 的比较

有一个面试题:

求打印结果,这其实就是考验你对虚拟机堆内对象创建和integer包装类的理解。

public static void main(String[] args) {

        Integer a = new Integer(100);
        Integer b = 100;
        int c = 100;
        Integer d = new Integer(100);
        System.out.println(a == d);
        System.out.println(a == b);
        System.out.println(a == c);
        System.out.println(b == c);
        System.out.println(c == d);


    }

首先看这几个的创建方式       

Integer a = new Integer(100): 

    对于这个没什么好说的,创建对象,在堆内存中分配一块内存空间,并调用<inin>方法实例化对象,返回对象的引用。

    创建的执行码(看不懂自己去学习一下,对自己很有好处)

    NEW java/lang/Integer
    DUP
    BIPUSH 100
    INVOKESPECIAL java/lang/Integer.<init> (I)V
    ASTORE 1

Integer b = 100:

   这里返回的也一个对象,因为这里在编译后的字节码中隐式的调用了Integer的valueOf方法,最终返回的是一个Integer对象,我们来看执行码:

    BIPUSH 100
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
    ASTORE 2

对于这个valueOf方法有必要说一下,我们先看一下方法

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

对于这个方法,当你创建一个值大于-128和小于一个你指定(或者默认的127)时,生成的对象会被放在一个数组中,当再一次调用时,传值相同时,获得都是同一个对象。


int c = 100:

常量入栈的一个操作,没啥好说的:

    BIPUSH 100
    ISTORE 3

有必要说一下,在一个线程栈的栈帧里,局部变量被放在局部变量表里,对于对象的取用只跟位置有关,跟我们声明的 int c 没有关系,简单的说 声明是给开发人员用的,字节码中这些东西都不存在的。

各种声明方式说完了,我们就来说说比较时的执行过程

包装类在和基本类型一起操作时,有一个自动拆箱的操作,具体是咋操作的,我们来看一下执行码:

System.out.println(a == c) :

    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ALOAD 1
    INVOKEVIRTUAL java/lang/Integer.intValue ()I
    ILOAD 3
    IF_ICMPNE L11
    ICONST_1
    GOTO L12
   L11
   FRAME SAME1 java/io/PrintStream
    ICONST_0
   L12
   FRAME FULL [[Ljava/lang/String; java/lang/Integer java/lang/Integer I java/lang/Integer] [java/io/PrintStream I]
    INVOKEVIRTUAL java/io/PrintStream.println (Z)V

我们可以看到在执行比较的时候隐式的调用了integer的intValue()方法获取到了integer的int类型的value值,所以无论是哪种integer对象的声明方式,最终和int值比较的时候都会自动拆箱后进行int值比较。

而integer对象比较就和对象类型比较一样了,最终比较的就是对象是不是同一个。

由于integer重写了equals方法,如果调用该方法比较,其实是比较的对象类内封装的int类型的值。

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

好了,关于integer和int类型的比较说完了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值