本文主要讲解的是包装类,以及重要的“128陷阱”,以及在介绍包装类时,所涉及到的自动拆装箱及其相关知识,以及一道相关的习题。
一、包装类的定义
包装类(Wrapper Class)是Java编程语言中的一个重要概念,用于将基本数据类型封装为对象类型。Java是一个面向对象的编程语言,但基本数据类型(如int、byte、float等)并不直接支持面向对象的特性,如继承、多态等。为了弥补这一不足,Java为每种基本数据类型都提供了一个对应的包装类,这些包装类位于java.lang包中。
具体来说,Java中的八种基本数据类型及其对应的包装类如下:
包装类的本质是一个类。
例:int类型的10与Integer类型的10有什么不同?
①int只是一个数据类型,只能定义10在内存中如何存储
②Integer是一个类,其中包含很多方法,比如a1可以调用equals()方法而a只能用==所判断。
二、包装类详解
public class Test {
public static void main(String[] args) {
Integer a1=10;
Integer a2=10;
System.out.println(a1==a2);
Integer a3=1000;
Integer a4=1000;
System.out.println(a3==a4);
}
包装类是引用数据类型,==在引用数据类型当中比较的是地址是否相同。
而a1==a2为true,a3==a4为false的答案就在Integer的valueOf()方法中,我们将数值在-128到127之间的数值都存储在一个catch数组当中。该数组相当于一个缓存。
数据-128-127之间直接返回该值在数组当中的地址,所以在-128-127之间的数值用==比较是相等的
而不在这个区域的数。需要新开辟一个内存空间所以不相等。即128陷阱。
128陷阱
答案就在Integen的value0f()方当中,我们将数值在-128-127之间的数值都存储在有一个catch数组当中,该数组相当于一个缓存,数据-128-127之间直接返回该值在数组当中的地址,所以在-128-127之间的数值用==-进行比较是相等的。而不在这个区间的数,需要新开辟一个内存空间,所以不相等。
此时若想了解a是如何存储的只需要了解Integer valueOf(),查看该方法,发现所传的值i在某一个范围之内会执行一个条语句,而不再该范围之内则会new Integer,开辟新的内存空间。
此时就能解释,为何a3与a4为何不等,因为他们在取值范围之外,导致a3与a4开辟了新的内存空间,所以两者不等。
关键是这个范围是多少呢?
此时在看Integer valueOf()方法的取值范围,先查看下限low,发现low的值为-128。
再看high的值,发现high的值为127。同时再看在此范围当中,会返回什么查看catch,发现catch是一个大小为256的数组,其值从-128到127。
此时发现,如果该值在-128到127之间,那么返回的是在该数组中与该值相同的同一块的值,此时就能解释a1与a2为何相同,因为二者指向同一块内存空间。而a3与a4则不在范围内,重新开辟一个新的空间。这个问题被人称为128陷阱。
valueOf会确定int值是否在一个区间(-128,127),如果不在则new(128陷阱)
三、自动拆装箱
自动拆装箱本身是一个方法。自动拆装箱是Java等编程语言中的一种特性,主要涉及基本数据类型(如int、double等)与它们对应的封装类(如Integer、Double等)之间的自动转换。具体来说,自动装箱是指将基本数据类型自动转换为封装类对象的过程,而自动拆箱则是将封装类对象自动转换为基本数据类型的过程。
1、自动装箱
自动装箱是指将基本数据类型自动转换为封装类对象的过程。
例如:Integer b=10;此时该代码会被编译成Integer b=Integer.valueOf(10),涉及到自动装箱。
2、自动拆箱
自动拆箱则是将封装类对象自动转换为基本数据类型的过程。
例如:Integer b=10; Int a=b;此时int a =b会被编译成int a=b.intvalue();涉及到自动拆箱。
四、习题
public class Test {
public static void main(String[] args) {
int a=10;
int b=10;
Integer a1=10;
Integer b1=10;
Integer a2=new Integer(10);
Integer b2=new Integer(10);
System.out.println(a==b);
System.out.println(a1==b1);
System.out.println(a2==b2);
System.out.println(a1==a);
System.out.println(a1.equals(a));
System.out.println(a1==a2);
System.out.println(a==a2);
}
① System.out.println(a==b);
输出:true
原因:基本数据类型==比较的是值,二者值相等返回true。
②System.out.println(a1==b1);
输出:true
原因:Integer类型中若值在-128到127之间,则从数组中找数据,==比较地址所以为true。
③System.out.println(a2==b2);
输出:false
原因:new是开辟新的空间,==比较地址所以为false。
④System.out.println(a1==a);
输出:true
原因:包装类类型与基本数据类型用==比较时,会自动拆箱,此时a1会变成int类型数据,比较值是否相同。
⑤System.out.println(a1.equals(a));
输出:true
原因:查看equals方法,发现会判断值是否是一个Integer类型如果是则进行拆箱,比较值是否相同。
⑥ System.out.println(a1==a2);
输出:false
原因:一个在数组当中,一个是new开辟新的空间,==比较地址所以为false。
⑦System.out.println(a==a2);
输出:true
原因:自动拆箱,然后进行值的比较。