基本数据类型的包装类
基本数据类型的包装类
八种基本数据类型并不是对象,为了将基本类型数据和对象之间实现互相转化,Java为每一个基本数据类型提供了相应的包装类。
包装类基本知识
为了解决这个不足,Java在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。
在这八个类名中,除了Integer和Character类以外,其它六个类的类名和基本数据类型一致,只是类名的第一个字母大写而已。
包装类源码解读
自动装箱:
基本类型的数据处于需要对象的环境中时,会自动转为“对象”。
我们以Integer为例:
Integer i = 5
Integer i = 100;//自动装箱 //相当于编译器自动为您作以下的语法编译: Integer i = Integer.valueOf(100);//调用的是valueOf(100),而不是new Integer(100)
自动拆箱:
每当需要一个值时,对象会自动转成基本数据类型,没必要再去显式调用intValue()、doubleValue()等转型方法。
Integer i = Integer.valueOf(5);
int j = i;
编译器会自动转成:int j = i.intValue();
这样的过程就是自动拆箱。
自动装箱/拆箱的本质是:
Integer i = 100; int j = i;//自动拆箱 //相当于编译器自动为您作以下的语法编译: int j = i.intValue();
自动装箱与拆箱的功能是所谓的“编译器蜜糖(Compiler Sugar)”,虽然使用这个功能很方便,但在程序运行阶段您得了解Java的语义。如下所示的程序是可以通过编译的:
【示例】包装类空指针异常问题
public class Test1 {
public static void main(String[ ] args) {
Integer i = null;
int j = i;
}
}
执行结果如图所示:
运行结果之所以会出现空指针异常,是因为如上代码相当于:
public class Test1 { public static void main(String[ ] args) { /*示例8-5的代码在编译时期是合法的,但是在运行时期会有错误 因为其相当于下面两行代码*/ Integer i = null; int j = i.intValue(); } }
包装类的缓存问题
整型、char类型所对应的包装类,在自动装箱时,对于-128~127之间的值会进行缓存处理,其目的是提高效率。
private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} } /** * 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 */ @HotSpotIntrinsicCandidate public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
总结
- 自动装箱调用的是valueOf()方法,而不是new Integer()方法。
- 自动拆箱调用的xxxValue()方法。
- 包装类在自动装箱时为了提高效率,对于-128~127之间的值会进行缓存处理。超过范围后,对象之间不能再使用==进行数值的比较,而是使用equals方法。