行文思路:
1 基本数据类型有哪些?分别是多少个字节?
2 包装类型与对应的基本数据类型有什么差别?
3 包装类型和基本数据类型各自在虚拟机的哪些位置?
4 为什么既要有包装类型,有要有基本类型的存在?【可以用他们的差别看来回答---》回看第二点】
5 什么时候适合使用包装类型?什么时候适合使用基本类型?
6 包装类型和基本数据类型的各种类型之间值的比较方式是什么?
7 拆箱装箱
----------------------------------------------------
1 基本数据类型有哪些以及对应的包装类型?分别是多少个字节?
数据类型 | 占用字节数 | |||||
byte[Byte]:1字节 | short[Short]:2字节 | char[Character]:2字节 | int[Integer]:4字节 | long[Long]:8字节 | flaot[Float]:4字节 | double[Double]:8字节 |
boolean[Boolean]:对虚拟机来说根本就不存在 boolean 这个类型,boolean类型在编译后会使用其他数据类型来表示。跟虚拟机的规范以及处理器规格【32位还是64位】有关,所以不确定。一个字节或者四个字节,都有可能。可参考:https://blog.csdn.net/dingpf1209/article/details/80259500 |
2 包装类型与对应的基本数据类型有什么差别?
a 包装类型可以为null,基本类型不可以
因为包装类型可以为null,所以使得包装类型可以应用于POJO【简单无规则的 Java 对象,只有属性字段以及 setter 和 getter 方法】 为什么 POJO 的属性必须要用包装类型呢?
数据库的查询结果可能是 null,如果使用基本类型的话,因为要自动拆箱(将包装类型转为基本类型,比如说把 Integer 对象转换成 int 值),就会抛出 NullPointerException 的异常。 --------《阿里巴巴 Java 开发手册》
b 包装类型可用于泛型,而基本类型不可以
理由:泛型在编译时会进行类型擦除,最后只保留原始类型,而原始类型只能是 Object 类及其子类,但是基本类型不是对象类型。
c 基本类型比包装类型更高效
基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用。
d 包装类型是对象的概念,比较的时候要注意==比较的是地址引用,同值不相等的情况,需要equal 重写比较值
e 自动拆箱和自动装箱【下文会详细提到】
3 包装类型和基本数据类型各自在虚拟机的哪些位置?
包装类型其实就是对象,所以很容易想到是在JVM的堆上,对于基本数据类型,要具体看java虚拟机栈是线程私有的,生命周期跟线程相同,每个方法调用的时候都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接
private int i;
}
- 在pojo类中定义的属性用包装类型
- 有时候需要null 的时候使用包装类型
- RPC 接口参数定义和返回值的时候用包装类型
- 局部变量一般用基本类型
- 反射方法调用的时候使用包装类型
6 包装类型和基本数据类型的各种类型之间值的比较方式是什么?
包装类型本质是对象,所以包装类型按对象处理 比较多的用equal 但是涉及精度问题解决的时候,采用相减取范围的方式解决,或者Double换 BigDecimal 采用complable接口实现等方式,涉及到精度要求比较高的时候,一定要注意。
基本类型直接==比较就可以,比较的是具体数值。
7 拆箱装箱
基本类型转换为包装类型的过程称为装箱,反之成为拆箱。eg:Integer.valueOf()为装箱代码,Integer.intValue()为拆箱
// 1)基本类型和包装类型 int a = 100; Integer b = 100; System.out.println(a == b); true // 2)两个包装类型 Integer c = 100; Integer d = 100; System.out.println(c == d); true // 3) Integer c = 200; Integer d = 200; System.out.println(c == d); false
解释:
第一个例子:用== ,b会自动拆箱,比较100==100 所以为true。
第二个例子:-128 到 127 之间的数会从 IntegerCache 中取,所以没有生成新的对象,对象为同一个地址。所以为true
第三个例子:超出范围,生成了新的对象。==比较的地址不同,为false。
ps: 当需要进行自动装箱时,如果数字在 -128 至 127 之间时,会直接使用缓存中的对象,而不是重新创建一个对象。