更细致的内容:什么是Java中的自动拆装箱
包装类 - 基本类型对照
装箱拆箱
拆箱方法
自动拆装箱
- 自动装箱均通过 valueOf 方法。
- 自动查询均通过 xxxValue()方法实现。
public static void main(String[]args){
Integer integer=1; //装箱
int i=integer; //拆箱
}
// 反编译
public static void main(String[]args){
Integer integer=Integer.valueOf(1);
int i=integer.intValue();
}
自动拆装箱的场景
- 使用
=
运算符。 - 泛型使用基本类型:装箱使用。
// 源代码
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i ++){
li.add(i);
}
// 反编译后的代码
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2){
li.add(Integer.valueOf(i));
}
- 包装类型和基本类型比较大小 :拆箱比较
// 源代码
Integer a=1;
System.out.println(a==1?"等于":"不等于");
Boolean bool=false;
System.out.println(bool?"真":"假");
// 反编译代码
Integer a=1;
System.out.println(a.intValue()==1?"等于":"不等于");
Boolean bool=false;
System.out.println(bool.booleanValue?"真":"假");
- 包装类型的运算
// 源代码
Integer i = 10;
Integer j = 20;
System.out.println(i+j);
// 编译代码
Integer i = Integer.valueOf(10);
Integer j = Integer.valueOf(20);
System.out.println(i.intValue() + j.intValue());
- 三目运算符的使用:
当第二,第三位操作数分别为基本类型和对象时,其中的对象就会拆箱为基本类型进行操作。
// 源代码
boolean flag = true;
Integer i = 0;
int j = 1;
int k = flag ? i : j;
// 编译代码
boolean flag = true;
Integer i = Integer.valueOf(0);
int j = 1;
int k = flag ? i.intValue() : j;
- 函数参数与返回值
//自动拆箱
public int getNum1(Integer num) {
return num;
}
//自动装箱
public Integer getNum2(int num) {
return num;
}
自动装箱和缓存
自动装箱触发的 valueOf
方法会发生缓存的功能。
如果数字在-128至127之间时,会直接使用缓存中的对象,而不是重新创建一个对象,这个数值可以通过 JVM 运行参数 java.lang.Integer.IntegerCache.high
进行设置.
public static void main(String... strings) {
Integer integer1 = 3;
Integer integer2 = 3;
if (integer1 == integer2)
System.out.println("integer1 == integer2");
else
System.out.println("integer1 != integer2");
Integer integer3 = 300;
Integer integer4 = 300;
if (integer3 == integer4)
System.out.println("integer3 == integer4");
else
System.out.println("integer3 != integer4");
}
- 注意:只有 整型, Boolean,Character才提供了缓存。
-128至127之间的整数。
true 和 false的布尔值。
‘\u0000’至 ‘\u007f’之间的字符。
自动拆箱和装箱带来的问题
- 包装对象的数值比较,不能简单的使用==,虽然-128到127之间的数字可以,但是这个范围之外还是需要使用equals比较。
- 前面提到,有些场景会进行自动拆装箱,同时也说过,由于自动拆箱,如果包装类对象为null,那么自动拆箱时就有可能抛出NPE。
- 如果一个for循环中有大量拆装箱操作,会浪费很多资源。