autoboxing and unboxing

探讨Java中自动装箱与拆箱的过程,并解析当数值在-128到127范围内时,Integer对象如何通过缓存机制实现引用相等的现象。文章通过示例代码说明了这一机制的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Why does 128==128 return false but 127==127 return true

 1 public static void autoboxingUnboxing(){
 2         Integer ta = 127;
 3         Integer tb = 127;
 4         Integer tc = 128;
 5         Integer td = 128;
 6         if(ta == tb) System.out.println("ta equals tb");
 7         if(tc == td) System.out.println("tc equals td");
 8         
 9     }
10 
11 
12 Output:
13 ta equals tb

When you compile a number literal in Java and assign it to a Integer (capital I) the compile emits:

Integer b2 =Integer.valueOf(127)

This line of code is also generated when you use autoboxing.

valueOf is implemented such that certain numbers are "pooled", and it returns the same instance for values smaller than 128.

From the java 1.6 source code, line 621:

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

The value of high can be configured to another value, with the system property.

-Djava.lang.Integer.IntegerCache.high=999

If you run your program with that system property, it will output true!

The obvious conclusion: never rely on two references being identical, always compare them with .equals() method.

So b2.equals(b3) will print true for all logically equal values of b2,b3.

 

 

private static class IntegerCache {
    private IntegerCache(){}

    static final Integer cache[] = new Integer[-(-128) + 127 + 1];

    static {
        for(int i = 0; i < cache.length; i++)
            cache[i] = new Integer(i - 128);
    }
}

public static Integer valueOf(int i) {
    final int offset = 128;
    if (i >= -128 && i <= 127) { // must cache 
        return IntegerCache.cache[i + offset];
    }
    return new Integer(i);
}

As correctly inferred, this caching code was added to support the object identity semantics of autoboxing for values between -128 and 127 (inclusive), as required by the language specification. Since the same object must be returned for integral values in this range, once the autoboxed value for, say, 0 is created, it must be retained until the virtual machine exits. That leaves the issue of whether or not the values in question are created eagerly or lazily and whether or not any container for those values is created eagerly or lazily.

转载于:https://www.cnblogs.com/reynold-lei/p/4367540.html

### Java中的装箱与拆箱 Java 提供了一种自动转换机制,称为 **装箱**(Boxing)和 **拆箱**Unboxing)。这种机制允许在原始数据类型(如 `int`, `double` 等)与其对应的包装类(如 `Integer`, `Double` 等)之间进行无缝转换。这一功能自 Java 5 引入以来极大地简化了开发者的编码过程[^1]。 #### 装箱(Boxing) 装箱是指将原始数据类型自动转换为其对应的包装类实例的过程。例如,当我们将一个 `int` 值赋给一个 `Integer` 对象时,JVM 会自动创建一个新的 `Integer` 实例来保存这个值。 ```java // Example of autoboxing Integer boxedValue = 42; // Automatically converts int to Integer object ``` 在此代码片段中,整数值 `42` 被隐式地转换成了 `Integer` 类型的对象[^1]。 #### 拆箱(Unboxing) 相反,拆箱则是指将包装类实例自动转换回其对应的原始数据类型的操作。例如,当我们从一个 `Integer` 对象中提取出它的基础 `int` 值时,即发生了拆箱行为。 ```java // Example of auto-unboxing int unboxedValue = boxedValue; // Automatically extracts int value from Integer object ``` 这里展示了如何将前面定义的 `Integer` 变量重新转回成普通的 `int` 数据类型[^1]。 需要注意的是虽然这些操作看起来很方便,但在某些情况下可能会引发性能问题或者 NullPointerExceptions 如果尝试对 null 引用执行拆箱动作的话[^3]。 --- ### 注意事项 尽管装箱/拆箱提供了便利性,但也存在一些潜在风险: - 性能开销:频繁地进行装箱或拆箱可能会影响应用程序的整体效率。 - NullPointer Exceptions:如果试图拆箱一个null引用,则会导致运行时错误。 因此,在实际项目开发过程中应当谨慎使用此类特性,并充分理解其中的工作原理以便更好地控制程序的行为。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值