Java面试题之128陷阱与装箱拆箱

题目一

第一部分

        int a = 123;
		int b = 123;
		Integer c = 123;
		Integer d = 123;
      	System.out.println(a == b);//true
		System.out.println(a == c);//true
		System.out.println(d == d);//true

在Java中,基本数据类型的比较使用的是值比较,而对象的比较默认使用的是引用比较。但是,Java对于值从-128到127之间的Integer对象做了特殊处理,它们会被自动缓存,所以当你创建这个范围内的Integer对象时,实际上会返回相同的引用。


这就是为什么以下代码中的比较都返回true

int a = 123;
int b = 123;
Integer c = 123;
Integer d = 123;
System.out.println(a == b); // true, 基本类型值比较
System.out.println(a == c); // true, `c`被自动拆箱为int类型,然后进行值比较。后文提到拆箱装箱
System.out.println(c == d); // true, `c`和`d`是在-128到127之间的Integer缓存引用

当比较的值超出这个范围,或者使用new Integer()创建对象时,相同值的Integer对象可能会有不同的引用,那么使用==进行比较就会返回false。在这种情况下,应该使用.equals()方法来比较对象的值。


第二部分

如果Integer的值是1280,那么即使两个Integer对象的值相同,使用==比较也会返回false。这是因为1280超出了Java自动缓存的-128到127的范围,所以每个Integer对象都会有不同的引用。


Integer x = 1280;
Integer y = 1280;
System.out.println(x == y); // 这将返回false
Integer x = 1280;
Integer y = 1280;
System.out.println(x.equals(y)); // 这将返回true


正确比较两个Integer对象的方法是使用.equals()方法,而不是==。这样可以比较对象的值,而不是它们的引用。

当处理大于127的Integer值时,始终使用.equals()方法来确保正确比较对象的值。

拆箱 装箱

装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。

例如: 

Integer i = 10;  //装箱
int n = i;   //拆箱

Java8种基本类型的自动装箱代码实现

//byte原生类型自动装箱成Byte
public static Byte valueOf(byte b) {
    final int offset = 128;
    return ByteCache.cache[(int)b + offset];
}


//short原生类型自动装箱成Short
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);
}

//char原生类型自动装箱成Character
public static Character valueOf(char c) {
    if (c <= 127) { // must cache
        return CharacterCache.cache[(int)c];
    }
    return new Character(c);
}

//int原生类型自动装箱成Integer
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

//long原生类型自动装箱成Long
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);
}

//double原生类型自动装箱成Double
public static Double valueOf(double d) {
    return new Double(d);
}


//float原生类型自动装箱成Float
public static Float valueOf(float f) {
    return new Float(f);
}
  • 18
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值