概要
Integer是java的一个包装类属于引用类型,而int是java中的一个基本数据类型,按理来说,他俩应该是不能相互赋值的,但总有这么几行下面的代码出现:
public class Main {
public static void main(String[] args) {
Integer i=10;
int a=i;
System.out.println(a);
}
}
运行结果如下:
可以看到是成功运行的,这又是为什么呢,其实在java中有两种思想,一种是自动装箱,一种是自动 拆箱
自动装箱与自动拆箱
自动装箱是指将java中基本数据类型的值直接赋值给包装类:
public class Main {
public static void main(String[] args) {
int i=10;
Integer a=i;
System.out.println(a);
}
}
自动拆箱是指java中的包装类的值直接赋值给基本数据类型:
public class Main {
public static void main(String[] args) {
Integer i=10;
int a=i;
System.out.println(a);
}
}
实现原理:
java中的自动装箱和自动拆箱的实现原理主要是通过编译器的语法糖(Syntactic Sugar)以及运行时的类型转换机制:
1.当发生自动装箱时JVM 将创建一个包装类的新实例,并将基本类型的值传递给该实例的构造函数。
2.当发生自动拆箱时,JVM会插入一个调用包装类的 xxx
Value()(对于Integer来说是intValue())
方法的语句,将包装类的值传入基本数据类型的变量中。
值得注意的是为了提升性能,部分数值会出现不同的变量会使用同一个引用:
public class Main {
public static void main(String[] args) {
Integer i=10;
Integer j=10;
System.out.println(i==j);
}
}
可以看到在对两者进行地址比较时显示为true,其实Integer i=10后,java会 将 i 这个对象存入缓存中,如果有相同数值,就指向同一个引用,不过这个数值是有范围的,通常是从 -128
到 127,也就是超过这个范围的数就会执行重建对象:
public class Main {
public static void main(String[] args) {
Integer i=200;
Integer j=200;
System.out.println(i==j);
}
}