一、包装类是什么?
Java中的包装类是用于将基本数据类型(如int、double、char等)封装为对象的特殊类。这些包装类使得基本数据类型能够具有对象的特性,如方法调用和属性赋值等。包装类在Java中扮演着重要的角色,特别是在需要将基本数据类型作为对象来处理时(如存储在集合中)。
java有着8种基本数据类型,整型(byte、short、int、long)、浮点型(float、double)、布尔型boolean、字符型char。
对应的,java提供了这八种数据类型对应的包装类,Byte、Short、Integer、Long、Float、Double、Boolean、Character
java中的数据类型int,double等不是对象,无法通过向上转型获取到Object提供的方法,而像String却可以,只因为String是一个对象而不是一个类型。基本数据类型由于这样的特性,导致无法参与转型,泛型,反射等过程。为了弥补这个缺陷,java提供了包装类。
二、包装类的主要特点
引用类型:包装类是Java中的引用类型,它们的对象都属于堆内存中的对象。
不可变性:包装类是不可变的,一旦创建了包装类的对象,就无法修改其值(除了StringBuilder和StringBuffer这类特殊的字符串包装类,它们支持修改)。
提供额外功能:包装类提供了一些额外的方法和属性,可以执行一些基本数据类型无法实现的操作,如字符串转换、数据比较等。
自动装箱与拆箱:Java 5及以后的版本提供了自动装箱和自动拆箱的功能,允许在基本数据类型和对应的包装类对象之间自动转换,简化了代码编写。
三、常用方法
包装类提供了许多有用的方法,包括但不限于:
xxxValue():将包装类对象转换为对应的基本数据类型(如intValue()、doubleValue()等)。
toString():将包装类的值转换为字符串。
valueOf():将基本数据类型或字符串转换为包装类对象。
equals(Object obj):比较两个包装类对象是否相等。
compareTo(T other):比较两个包装类对象的大小关系(适用于实现了Comparable接口的包装类)。
parseXxx(String s):将字符串解析为对应的基本数据类型(如parseInt()、parseDouble()等)。
四、自动拆装箱
在编译器将.java文件编译称为.class的文件这个过程当中,我们通过包装类创建的对象会被进行自动拆装箱。
装箱:将基本数据类型转化为包装类型
拆箱:将包装类型转化为基本数据类型
Integer b = 10;
//自动装箱
//会被编译成 Integer b = Integer.valueOf(10);
int a = b;
//自动拆箱
//会被编译成 int a = b.intValue();
五、128陷阱
128陷阱是重点,需要搞清楚。
如图,我们可以看到用包装类型Integer定义,两种情况仅数值大小不同,结果却发生了变化。
我们可以按ctrl点击Integer,在valueOf()中寻找答案。
根据这两张图片我们可以看出当范围在[-128,127]直接是存储在 cache数组之中。
答案就在Integer的value0f()方当中,我们将数值在-128-127之间的数值都存储在有一个catch数组当中,该数组相当于一个缓存, 数据-128-127之间直接返回该值在数组当中的地址,所以在-128-127之间的数值用==进行比较是相等的。而不在这个区间的数,需要新开辟一个内存空间,所以不相等。
六、例题
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);
}
1.基本数据类型 == 比较值
2.128陷阱
3.引用数据类型 == 比较地址
4.用 == 判断,自动拆箱
5.用 equals() 判断,自动装箱
6.引用数据类型 == 比较地址
7.a2自动拆箱