包装类
文章目录
包装类01–基本使用
对比引用类型,基本类型存在的一些缺陷:
- 无法表示不存在的值(
null
值) - 不能利用面向对象的方式去操作基本类型(比如直接用基本类型调用方法)
- 当方法参数是引用类型时,基本类型无法传递
解决方案:可以自己将基本类型包装成引用类型
- 其实Java中已经内置了基本类型的包装类(都在java.lang包中)
- 数字类型的包装类(Byte\Short\Integer\Long\Float\Double)最终都继承自java.lang.Number
包装类02–细节
自动装箱、拆箱(Autoboxing and Unboxing)
- 自动装箱:Java 编译器会自动将基本类型转换为包装类(调用
valueOf
方法) - 自动拆箱:Java 编译器会自动将包装类转换为基本类型(调用
xxxValue
方法)
自动装箱示例:Java 编译器会帮我们做很多工作,过一遍下面的示例即可。
Integer i1 = 10; // 自动装箱
// 等价于 Integer i1 = Integer.valueOf(10);
Object num = 10; // 自动装箱
// 等价于: Object num1 = Integer.valueOf(10);
public static void main(String[] args) {
add(20); // 自动装箱
// 等价于 add(Integer.valueOf(20));
}
static void add(Integer num) {}
自动拆箱示例:平时写代码这些都是不需要我们操心的,了解原理即可。
Integer i1 = 10;
int i2 = i1; // 自动拆箱
// 等价于: int i2 = i1.intValue();
System.out.println(i1 == 10); // 自动拆箱
// 等价于: System.out.println(i1.intValue() == 10);
Integer[] array = { 11, 22, 33, 44 }; // 包装类数组
int result = 0;
for (Integer i : array) {
// i.intValue() % 2 == 0
if (i % 2 == 0) { // 自动拆箱
// result += i.intValue();
result += i; //自动拆箱
}
}
包装类的判等
- 包装类的判等,不要使用
==
、!=
运算符,应该使用equals
方法
// 缓存范围: [-128, 127]
Integer i1 = 88;
Integer i2 = 88;
Integer i3 = 888;
Integer i4 = 888;
// 不推荐, 比较的是内存地址
System.out.println(i1 == i2); // true, 为什么呢? 缓存, 具体看下面
System.out.println(i3 == i4); // false
// 推荐, 先比内存地址, 再比值
System.out.println(i1.equals(i2)); // true
System.out.println(i3.equals(i4)); // true
你可能会好奇为什么 i1 == i2
会返回 true
,是因为:
IntegerCache
类中缓存了 [-128, 127] 范围的Integer
对象(因为很常用)Integer.valueOf
方法会优先去IntegerCache
缓存中获取Integer
对象
// 缓存范围: [-128, 127]
Integer i1 = 88; // 从IntegerCache缓存中取值
Integer i2 = Integer.valueOf(88); // 从IntegerCache缓存中取值
Integer i3 = new Integer(88); // new 出来的对象必然是一个新的地址
System.out.println(i1 == i2); // true
System.out.println(i2 == i3); // false
查看 Java 源码可以知道 valueOf
方法与 new
对象不完全等价, valueOf
是先判断缓存中是否有该值,没有再去new
。
包装类使用注意
- 【基本类型数组】与【包装类数组】之间是不能自动装箱、拆箱
public static void main(String[] args) {
// 基本类型数组不会自动装箱
int[] nums1 = { 11, 22 };
// test1(nums1); // error
// Integer[] nums2 = nums1; // error
// 包装类数组不会自动拆箱
Integer[] nums3 = { 11, 22 };
// test2(num3); // error
// int[] nums4 = num3; //error
}
static void test1(Integer[] nums) {}
static void test2(int[] nums) {}