Java 基本数据(Primitive)类型的自动装箱(autoboxing)、拆箱(autounboxing)是自J2SE 5.0开始提供的功能。java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装成为装箱,解包装称为拆箱)。
自动装箱 Java 八种基本数据类型在某些条件下使用会自动变为对应的包装器类型,举例 Integer(int)类型如下:
@Test public void boxing(){ Integer i1 = 10; Integer i2 = 10; Integer i3 = 128; Integer i4 = 128; System.out.println("i1==i2: " + (i1 == i2)); System.out.println("i3==i4: " + (i3 == i4)); System.out.println("i1.equals(i2): " + i1.equals(i2)); System.out.println("i3.equals(i4): " + i3.equals(i4)); }
输出结果如下:
i1==i2: true i3==i4: false i1.equals(i2): true i3.equals(i4): true
1.当包装器类型进行“==”比较时,i3会调用 Integer.valueOf() 自动装箱基本数据类型为包装器类型,源码如下:
/** * Returns an {@code Integer} instance representing the specified * {@code int} value. If a new {@code Integer} instance is not * required, this method should generally be used in preference to * the constructor {@link #Integer(int)}, as this method is likely * to yield significantly better space and time performance by * caching frequently requested values. * * This method will always cache values in the range -128 to 127, * inclusive, and may cache other values outside of this range. * * @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 */ public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
Integer 对象自动缓存int值范围在low~high(-128~127),如果超出这个范围则会自动装箱为包装类。
2.Integer包装类实现 equals 方法中,只要比较的当前对象是 Integer 实例就会自动拆箱为基本数据类型。Integer类的equals方法的源码如下:
/** * Compares this object to the specified object. The result is * {@code true} if and only if the argument is not * {@code null} and is an {@code Integer} object that * contains the same {@code int} value as this object. * * @param obj the object to compare with. * @return {@code true} if the objects are the same; * {@code false} otherwise. */ public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
而其他类型实现如下:
1)Integer、Short、Byte、Character、Long这几个包装类 valueOf() 或者 intValue() 方法实现类似 2)Double、Float的 valueOf() 或者 intValue() 方法的实现类似 3)Boolean的 valueOf() 或者 intValue() 方法实现是个三目运算,如 return (b ? TRUE : FALSE);
自动拆箱 Java 八种包装器类型在某些条件下使用会自动变为对应的基本数据类型,举例 int(Integer)类型如下:
@Test public void boxing(){ Integer i1 = 10; int i2 = 10; int i3 = 128; Integer i4 = 128; System.out.println("i1==i2: " + (i1 == i2)); System.out.println("i3==i4: " + (i3 == i4)); }
输出结果如下:
i1==i2: true i3==i4: true
程序执行时i4会调用 Integer.intValue() 方法自动拆箱包装器类型为基本数据类型,源码如下:
/** * Returns the value of this {@code Integer} as an * {@code int}. */ public int intValue() { return value; }
包装器类型和基本数据类型进行“==”比较时,包装器类型会自动拆箱为基本数据类型。
注意:equals() 比较的是两个对象的值(内容)是否相同,而 "==" 比较的是两个对象的引用(内存地址)是否相同,也用来比较两个基本数据类型(int)的变量值是否相等。“==”运算符的两个操作数都是包装器类型的引用时比较指向的是否是同一个对象,而其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程),对于包装器类型 equals 方法并不会进行类型转换。