Java面试题基本数据类型自动装箱和自动拆箱原理剖析
Java中数据类型可以划分为两种,一种是Primitive Type(基本类型),另外一种是Reference Type(引用类型)。基本类型的数值不是Object对象,不能调用对象的toString()、getClass()等方法。Java提供了针对每种基本类型的包装类型,如下图所示:
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));
}
输出结果如图:
1.当包装器类型进行“==”比较时,i3会调用 Integer.valueOf() 自动装箱基本数据类型为包装器类型,源码如下:
Integer 对象自动缓存int值范围在low~high(-128~127),如果超出这个范围则会自动装箱为包装类。
2.Integer包装类实现 equals 方法中,只要比较的当前对象是 Integer 实例就会自动拆箱为基本数据类型。Integer类的equals方法的源码如下:
而其他类型实现如下:
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));
}
输出结果如图:
程序执行时i4会调用 Integer.intValue() 方法自动拆箱包装器类型为基本数据类型,源码如下:
包装器类型和基本数据类型进行“==”比较时,包装器类型会自动拆箱为基本数据类型。
源码参考:http://blog.yoodb.com/yoodb/article/detail/1085,微信“引用”功能,会导致java编码格式问题,建议手动敲写代码或者源码参考此路径。
注意:equals() 比较的是两个对象的值(内容)是否相同,而 "==" 比较的是两个对象的引用(内存地址)是否相同,也用来比较两个基本数据类型(int)的变量值是否相等。“==”运算符的两个操作数都是包装器类型的引用时比较指向的是否是同一个对象,而其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程),对于包装器类型 equals 方法并不会进行类型转换。
优哉游哉
更多推荐:《优哉游哉》
涵盖:程序人生、搞笑视频、算法与数据结构、黑客技术与网络安全、前端开发、Java、Python、Redis缓存、Spring源码、各大主流框架、Web开发、大数据技术、Storm、Hadoop、MapReduce、Spark、elasticsearch、单点登录统一认证、分布式框架、集群、安卓开发、iOS开发、C/C++、.NET、Linux、Mysql、Oracle、NoSQL非关系型数据库、运维等。