如何理解Java自动装箱与拆箱?

1 个回答

  • 孙吴
    莫愁前路无知己,天下谁人不识君。
    #### 定义 - **自动装箱**:将基本数据类型自动转换为对应的包装器类型,例如 `int` 转换为 `Integer`。调用方法:`Integer.valueOf(int)` - **自动拆箱**:将包装器类型自动转换为基本数据类型,例如 `Integer` 转换为 `int`。调用方法:`Integer.intValue()` #### 例子 在 Java SE 5 之前,生成一个数值为 10 的 `Integer` 对象需要这样做: ```java Integer i = new Integer(10); ``` 从 Java SE 5 开始,提供了自动装箱的特性,可以简化为: ```java Integer i = 10; ``` ### 面试题 1:以下代码会输出什么? ```java public class Main { public static void main(String[] args) { Integer i1 = 100; Integer i2 = 100; Integer i3 = 200; Integer i4 = 200; System.out.println(i1 == i2); // true System.out.println(i3 == i4); // false } } ``` #### 运行结果 ```plaintext true false ``` #### 原因分析 输出结果表明 `i1` 和 `i2` 指向的是同一个对象,而 `i3` 和 `i4` 指向的是不同的对象。这是因为 `Integer` 的 `valueOf` 方法的实现如下: ```java public static Integer valueOf(int i) { if (i >= -128 && i <= IntegerCache.high) { return IntegerCache.cache[i + 128]; } else { return new Integer(i); } } ``` `IntegerCache` 类的实现为: ```java private static class IntegerCache { static final int high; static final Integer cache[]; static { final int low = -128; int h = 127; if (integerCacheHighPropValue != null) { int i = Long.decode(integerCacheHighPropValue).intValue(); i = Math.max(i, 127); h = Math.min(i, Integer.MAX_VALUE - (-low)); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for (int k = 0; k < cache.length; k++) { cache[k] = new Integer(j++); } } private IntegerCache() {} } ``` 通过 `valueOf` 方法创建 `Integer` 对象时,如果数值在 `[-128, 127]` 之间,会返回 `IntegerCache.cache` 中已经存在的对象的引用,否则创建一个新的 `Integer` 对象。因此,`i1` 和 `i2` 的数值为 100,从缓存中取出相同的对象引用,而 `i3` 和 `i4` 的数值为 200,创建了不同的对象。 ### 面试题 2:以下代码输出什么? ```java public class Main { public static void main(String[] args) { Double i1 = 100.0; Double i2 = 100.0; Double i3 = 200.0; Double i4 = 200.0; System.out.println(i1 == i2); // false System.out.println(i3 == i4); // false } } ``` #### 运行结果 ```plaintext false false ``` #### 原因分析 在 Java 中,浮点数的缓存机制不同于整型数值。由于浮点数的范围和个数远远大于整型数值,JVM 并没有对浮点数进行缓存优化,因此 `i1` 和 `i2`,`i3` 和 `i4` 都指向不同的对象,所以比较引用时均返回 `false`。 ### 总结 - **自动装箱**:将基本类型自动转换为包装器类型。 - **自动拆箱**:将包装器类型自动转换为基本类型。 - **缓存机制**:`Integer` 对象在 `[-128, 127]` 范围内有缓存,比较引用相等时可能返回 `true`;`Double` 对象没有类似的缓存机制,因此比较引用相等时返回 `false`。
    编辑于 2024-05-27 23:04 •IP属地 北京
    举报
    评论
    收藏1