java中自动打包+解包机制(又称自动装箱,拆箱)Auto-Boxing,UnBoxing
装箱应该理解为封装对象,即把基础数据类型(如 int)转换成基础类型封装类的对象(如 new Integer())
拆箱就是装箱的反过程,即把基础类型封装类的对象(如 new Integer())转换为基础数据类型(如 int)。
自动装箱与拆箱的功能事实上是编译器来帮您的忙,编译器在编译时期依您所编写的语法,决定是否进行装箱或拆箱动作。例如:
Integer i = 100;相当于编译器自动为您作以下的语法编译:
Integer i = new Integer(100);所以自动装箱与拆箱的功能是所谓的“编译器蜜糖”(Compiler Sugar),虽然使用这个功能很方便,但在程序运行阶段您得了解Java的语义。例如下面的程序是可以通过编译的:
Integer i = null;int j = i;这样的语法在编译时期是合法的,但是在运行时期会有错误,因为这种写法相当于:
Integer i = null;int j = i.intValue();null表示i没有参考至任何的对象实体,它可以合法地指定给对象参考名称。由于实际上i并没有参考至任何的对象,所以也就不可能操作intValue()方法,这样上面的写法在运行时会出现NullPointerException错误。
自动装箱、拆箱的功能提供了方便性,但隐藏了一些细节,所以必须小心。再来看范例4.6,您认为结果是什么呢?
范例4.6 AutoBoxDemo2.java
public class AutoBoxDemo2 {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
if (i1 == i2)
System.out.println("i1 == i2");
else
System.out.println("i1 != i2");
}}
从自动装箱与拆箱的机制来看,可能会觉得结果是显示i1 == i2,您是对的。那么范例4.7的这个程序,您觉得结果是什么?
范例4.7 AutoBoxDemo3.java
public class AutoBoxDemo3 {
public static void main(String[] args) {
Integer i1 = 200;
Integer i2 = 200;
if (i1 == i2)
System.out.println("i1 == i2");
elseSystem.out.println("i1 != i2");
}
}
结果是显示i1 != i2,这有些令人惊讶,两个范例语法完全一样,只不过改个数值而已,结果却相反。
其实这与==运算符的比较有关,在第3章中介绍过==是用来比较两个基本数据类型的变量值是否相等,事实上==也用于判断两个对象引用名称是否参考至同一个对象。
在自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,所以范例4.6中使用==进行比较时,i1 与 i2实际上参考至同一个对象。如果超过了从–128到127之间的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象,所以范例4.7使用==进行比较时,i1与i2参考的是不同的对象。
所以不要过分依赖自动装箱与拆箱,您还是必须知道基本数据类型与对象的差异。范例4.7最好还是依正规的方式来写,而不是依赖编译器蜜糖(Compiler Sugar)。例如范例4.7必须改写为范例4.8才是正确的。
Ü 范例4.8 AutoBoxDemo4.java
public class AutoBoxDemo4 {
public static void main(String[] args) {
Integer i1 = 200;
Integer i2 = 200;
if (i1.equals(i2))
System.out.println("i1 == i2");
else
System.out.println("i1 != i2");
}
结果这次是显示i1 == i2。使用这样的写法,相信也会比较放心一些,对于这些方便但隐藏细节的功能到底要不要用呢?基本上只有一个原则:如果您不确定就不要用。
相关推荐
Java高级特性:反射、泛型、注释符、自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入。随书附赠光盘内容为《Java高手真经(编程基础卷):Java核心编程技术》各种原型包、系统源程序。
Java高级特性:反射、泛型、注释符、自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入。随书附赠光盘内容为《Java高手真经(编程基础卷):Java核心编程技术》各种原型包、系统源程序。
Java高级特性:反射、泛型、注释符、自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入。随书附赠光盘内容为《Java高手真经(编程基础卷):Java核心编程技术》各种原型包、系统源程序。
Java高级特性:反射、泛型、注释符、自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入。随书附赠光盘内容为《Java高手真经(编程基础卷):Java核心编程技术》各种原型包、系统源程序。
Java高级特性:反射、泛型、注释符、自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入。随书附赠光盘内容为《Java高手真经(编程基础卷):Java核心编程技术》各种原型包、系统源程序。《Java高手...
1 自动装箱和拆箱 16. 2 新的for循环 16. 3 枚举类型 16. 4 静态导入 16. 5 可变长参数Varargs 16. 6 格式化输出 16. 7 使用ProcessBuilder执行本地命令 16. 8 泛型编程 16. 9 ...
4.2.2 自动装箱、拆箱 92 4.2.3 装箱的内幕 93 4.3 数组对象 96 4.3.1 数组基础 96 4.3.2 操作数组对象 99 4.3.3 数组复制 105 4.4 字符串对象 108 4.4.1 字符串基础 108 4.4.2 字符串特性 111 ...
自动装箱和拆箱; 新的for循环; 枚举类型; 静态导入; 格式化输出; 使用ProcessBuilder执行本地命令; 泛型编程; 监控和管理虚拟机;新的线程执行架构; 线程锁; 线程条件; 线程同步装置:semaphore countdownlatch ...
JAVA基础面试题总结1 JVM,JDK,JRE,字节码详解,Java 基本数据类型,装箱和拆箱
自动装箱拆箱 jdk.longaccumulator 计数器 jdk.threadlocal DateFormatService: 如何线程安全的使用 SimpleDateFormat jdk.volatilex VolatileArrays: volatile 例子 jdk.collection.union JDK: javaAPI 方式 ...
型叫做装箱,从封装类型到基本数据类型叫拆箱,自动拆装箱是jdk5.0提供的新特特性 2.3当我们要调用的方法中存在重载的时候,即基本类型数据作为唯一参数的方法与 该基本类型包装类作为唯一参数的方法重载,这时候...
基础概念与常识 Java 语言有哪些特点? JVM vs JDK vs JRE JVM JDK 和 JRE 什么是字节码?采用字节码的好处是什么? 为什么说 Java 语言“编译与解释并存”?...Oracle JDK vs OpenJDK ...自动装箱与拆箱了解吗?原理是什么?
1.面向对象和面向过程的区别以及...13.自动装箱与拆箱 14.在一个静态方法内调用一个非静态成员为什么是非法的 15.在 Java 中定义一个不做事且没有参数的构造方法的作用 16. import java 和 javax 有什么区别 17.....
文章目录什么是Java...自动装箱与拆箱说说&和&&的区别short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1; 有什么错?char 型变量中能不能存贮一个中文汉字?为什么?面向对象Java 面向对象编程三大特性: 封装
jdk1.5新特性 1.泛型 2.foreach 3.自动拆箱装箱 4.枚举 5.静态导入(Static import) 6.元数据(Metadata) 7.线程池 8.Java Generics
3.19 Java包装类、拆箱和装箱详解 54 3.20 包装类的应用 54 3.20.1.1 1) 实现 int 和 Integer 的相互转换 54 3.20.1.2 2) 将字符串转换为整数 55 3.20.1.3 3) 将整数转换为字符串 55 3.21 自动拆箱和装箱 56 3.22 再...
自动装箱和拆箱?autoboxing,unboxing 119 字符串相关类(String、 StringBuffer 、 StringBuilder) 120 String类的常用方法(已讲过,不再讲!) 120 StringBuffer和StringBuilder 121 String和StringBuffer和...