专业编程基础技术教程

网站首页 > 基础教程 正文

Integer常见面试题

ccvgpt 2024-08-06 12:35:02 基础教程 41 ℃

我们先来看一下下面这两个例子

public class IntegerDemo {

    public static void main(String[] args) {

        Integer a = 100;
        Integer b = 100;
        int c = 100;
        Integer d = new Integer(100);
        Integer e = Integer.valueOf(100);

        System.out.println(a == b);
        System.out.println(a == c);
        System.out.println(a == d);
        System.out.println(a == e);
        System.out.println(c == d);
        System.out.println(c == e);

    }

}
public class IntegerDemo {

    public static void main(String[] args) {

        Integer a = 200;
        Integer b = 200;
        int c = 200;
        Integer d = new Integer(200);
        Integer e = Integer.valueOf(200);
        Integer f = new Integer(200);

        System.out.println(a == b);
        System.out.println(a == c);
        System.out.println(a == d);
        System.out.println(a == e);
        System.out.println(c == d);
        System.out.println(c == e);
        System.out.println(d == f);

    }
}

看到这里,我们不经需要发出灵魂拷问,为什么仅仅改变了int的值,执行的结果就不太一样了

Integer常见面试题

我们来我们使用javap -v命令这个类的class文件,看看以不同的形式定义Integer对象,底层都是怎么处理的

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=7, args_size=1
         0: bipush        100
         2: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
         5: astore_1
         6: bipush        100
         8: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        11: astore_2
        12: bipush        100
        14: istore_3
        15: new           #3                  // class java/lang/Integer
        18: dup
        19: bipush        100
        21: invokespecial #4                  // Method java/lang/Integer."<init>":(I)V
        24: astore        4
        26: bipush        100
        28: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        31: astore        5
        33: new           #3                  // class java/lang/Integer
        36: dup
        37: bipush        100
        39: invokespecial #4                  // Method java/lang/Integer."<init>":(I)V
        42: astore        6
        44: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
        47: aload_1
        48: aload_2
        49: if_acmpne     56
        52: iconst_1
        53: goto          57
        56: iconst_0
        57: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
        60: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
        63: aload_1
        64: invokevirtual #7                  // Method java/lang/Integer.intValue:()I
        67: iload_3
        68: if_icmpne     75
        71: iconst_1
        72: goto          76
        75: iconst_0
        76: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
        79: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
        82: aload_1
        83: aload         4
        85: if_acmpne     92
        88: iconst_1
        89: goto          93
        92: iconst_0
        93: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
        96: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
        99: aload_1
       100: aload         5
       102: if_acmpne     109
       105: iconst_1
       106: goto          110
       109: iconst_0
       110: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
       113: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
       116: iload_3
       117: aload         4
       119: invokevirtual #7                  // Method java/lang/Integer.intValue:()I
       122: if_icmpne     129
       125: iconst_1
       126: goto          130
       129: iconst_0
       130: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
       133: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
       136: iload_3
       137: aload         5
       139: invokevirtual #7                  // Method java/lang/Integer.intValue:()I
       142: if_icmpne     149
       145: iconst_1
       146: goto          150
       149: iconst_0
       150: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
       153: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
       156: aload         4
       158: aload         6
       160: if_acmpne     167
       163: iconst_1
       164: goto          168
       167: iconst_0
       168: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
       171: return

我们着重来看一下main方法这一段

Integer a = 100;对应着这段代码

0: bipush 100 2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 5: astore_1

从这段代码可以看出来,Java是使用Integer.valueOf来实现自动装箱的

int和Integer进行比较时,会自动拆箱,转成int比较值,英雌,int和对应的包装类Integer是相等的,这个比较简单,就不过多分析了,我们来着重分析一下new Integer(value)和Integer.valueOf(value)

public Integer(int value) {
    this.value = value;
}

static final int low = -128;
static final int high;(默认127)

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

我们看出来使用valueOf方法时,在-128到127之间,会使用缓存,而使用new时,会直接创建一个新的对象,因此当int的值在-128到127之间,并且使用Integer.valueOf(包括自动装箱)方法创建对象时,使用==比较对象是相等的,使用new关键字会创建一个新的对象,因此==比较地址不相等

其他基本数据类型

我们子阿来看一下其他基本类型

public static Byte valueOf(byte b) {
    final int offset = 128;
    return ByteCache.cache[(int)b + offset];
}

public static Short valueOf(short s) {
    final int offset = 128;
    int sAsInt = s;
    if (sAsInt >= -128 && sAsInt <= 127) { // must cache
        return ShortCache.cache[sAsInt + offset];
    }
    return new Short(s);
}

public static Long valueOf(long l) {
    final int offset = 128;
    if (l >= -128 && l <= 127) { // will cache
        return LongCache.cache[(int)l + offset];
    }
    return new Long(l);
}

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}

public static Character valueOf(char c) {
    if (c <= 127) { // must cache
        return CharacterCache.cache[(int)c];
    }
    return new Character(c);
}


public static Float valueOf(float f) {
    return new Float(f);
}

public static Double valueOf(double d) {
    return new Double(d);
}

我们看到,除了Float和Double,其他基本类型的包装类,在-128到127之间都有缓存,因此,我们在比较的时候,需要注意

最近发表
标签列表