自动装箱和拆箱
自动装箱(autoboxing)和拆箱(unboxing):将基本数据类型和包装类自动转换。
自动装箱:
基本类型的数据处于需要对象的环境中时,会自动转为“对象”。我们以Integer为例:
Integer i = 5
编译器会自动转成:Integeri=Integer.valueOf(5),这就是Java的自动装箱。
自动拆箱:
每当需要一个值时,对象会自动转成基本数据类型,没必要再去显式调用intValue()、doubleValue()等转型方法。
Integer i = Integer.valueOf(5);
intj=i;
编译器会自动转成:int j=i.intValue();这样的过程就是自动拆箱。
自动装箱/拆箱的本质是:
自动装箱与拆箱的功能是编译器来帮忙,编译器在编译时依据您所编写的语法,决定是否进行装箱或拆箱动作。
【例】自动装箱
Integeri=100;//自动装箱
//相当于编译器自动为您作以下的语法编译:
Integeri=Integer.valueOf100);//调用的是valueOf(100),而不是new Integer(100)
【例】自动拆箱
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;
}
}
执行结果所示:
Exception in thread "main" java.lang.NullPointerException
at cn.sxt.gao1.Test1.main(Test1.java:5)
运行结果之所以会出现空指针异常,是因为如上代码相当于:
public class Test1 {
public static void main(String[ ] args) {
/*示例8-5的代码在编译时期是合法的,但是在运行时期会有错误因为其相当于下面两行代码*/
Integer i = null;
int j = i.intValue(0;
}
}
包装类的缓存问题
整型、char类型所对应的包装类,在自动装箱时,对于-128~127之间的值会进行缓存处理,其目的是提高效率。
缓存原理为:如果数据在-128~127这个区间,那么在类加载时就已经为该区间的每个数值创建了对象,并将这256个对象存放到一个名为cache的数组中。每当自动装箱过程发生时(或者手动调用valueOf()时),就会先判断数据是否在该区间,如果在则直接获取数组中对应的包装类对象的引用,如果不在该区间,则会通过new调用包装类的构造方法来创建对象。
下面我们以Integer类为例,看一看Java为我们提供的源码,加深对缓存技术的理解,如示例所示。
【例】Integer类相关源码
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
这段代码中我们需要解释下面几个问题:
1.IntegerCache类为Integer类的一个静态内部类,仅供Integer类使用。
2.一般情况下IntegerCache.low为-128,IntegerCache.high为127,IntegerCache.cache为内部类的一个静态属性。
以上就是小编为大家整理的关于JAVA的知识。
后续持续更新,还望诸君多多学习,早日上岸!
需要学习具体教程的可以关注私信我哦!