包装类简介
包装类将基本数据类型包装成对象,用于集合操作等操作
常见包装类
基本数据类型与包装类对照表:
基本数据类型 | 包装类 |
---|---|
byte |
Byte |
short |
Short |
int |
Integer |
long |
Long |
float |
Float |
double |
Double |
char |
Character |
boolean |
Boolean |
创建方法
通过有参构造器创建
包装类不存在无参构造方法,
通过valueOf()创建
一个常用静态方法,它用于将给定的基本数据类型或字符串转换为对应的包装类对象
|
|
自动装箱和自动拆箱
定义
自动装箱(Autoboxing):指的是 Java 编译器自动将基本数据类型转换为它们对应的包装类型。比如,将 int
转换为 Integer
。
自动拆箱(Unboxing):指的是 Java 编译器自动将包装类型转换为基本数据类型。比如,将 Integer
转换为 int
。
主要作用
-
它在 Java 5 中引入,主要是为了提高代码的可读性,减少手动转换操作,简化了代码编写,开发者可以更方便地在基本类型和包装类型之间进行转换。
-
常见于:
-
集合类如
List<Integer>
中无法存储基本类型,通过自动装箱,可以将int
转换为Integer
存入集合。1 2 3 4
int i = 99; //声明基础数据类型int变量 ArrayList list = new ArrayList(); list.add(i); //触发自动装箱,int类型自动转换成 Integer System.out.println(list);
-
自动装箱和拆箱经常在算术运算中出现,尤其是包装类型参与运算时。
-
底层实现
自动装箱和拆箱并不是通过语法糖实现的,它是通过调用包装类型的 valueOf()
和 xxxValue()
方法实现的。
- 自动装箱调用:
Integer.valueOf(int i)
- 自动拆箱调用:
Integer.intValue()
示例:
|
|
注意点
性能影响
自动装箱和拆箱虽然简化了编码,但在频繁使用的场景,可能导致性能开销,尤其是在循环中频繁发生装箱或拆箱时,容易引入不必要的对象创建和垃圾回收。
所以尽量避免在性能敏感的代码中频繁使用自动装箱和拆箱。例如:
|
|
NullPointerException
在进行拆箱操作时,如果包装类对象为 null,会抛出 NullPointerException。
计算方法
Java 允许包装类和基本数据类型之间的自动转换,因此你可以直接对包装类对象进行算术运算,Java 会自动进行拆箱和装箱。
缓存机制
包装类型中的 Byte
、Short
、Integer
和 Long
对某些范围内的值(例如 Integer,Long,Byte
缓存 -128 到 127)会使用对象缓存来提升性能。因此,同一数值的包装类型对象可能是同一个实例。
在 -128
到 127
范围内的 Integer
对象会被缓存和复用。
包装类的存在意义
存在意义就是将基本数据类型封装成对象
对象封装的好处
- 可以把属性也就是数据跟处理这些数据的方法结合在一起,比如Integer就有parseInt()等方法来专门处理int型相关的数据。
- Java中绝大部分方法或类都是用来处理类类型对象的,如ArrayList集合类就只能以类作为他的存储对象,
- 在Java中,泛型只能使用引用类型,而不能使用基本类型。
包装类和基本数据类型的对比
- 基本类型和引用类型 :基本数据类型是Java中最基本的数据类型,它们是预定义的,不需要实例化就可以使用。而引用类型则需要通过实例化对象来使用。这意味着,使用基本数据类型来存储一个整数时,不需要任何额外的内存分配,而使用包装类时,必须为对象分配内存。在性能方面,基本数据类型的操作通常比相应的引用类型快。
- 自动装箱和拆箱 :包装可以实现自动装箱和拆箱。自动装箱是指将基本类型转化为相应的包装类类型,而自动拆箱则是将包装类类型转化为相应的基本类型。这使得Java程序员更加方便地进行数据类型转换。
- 空指针异常 :int变量可以直接赋值为0,而Integer变量必须通过实例化对象来赋值。如果对一个未经初始化的Integer变量进行操作,就会出现空指针异常。这是因为它被赋予了null值,而null值是无法进行自动拆箱的。
- 性能区别 :基本数据类型占用内存小,效率高,适合频繁使用的简单操作。包装类因为是对象,涉及内存分配和垃圾回收,性能相对较低。
- 比较方式 :基本数据类型比较用
==
,直接比较数值。包装类比较时,==
比较的是对象的内存地址,而equals()
比较的是对象的值。 - 存储方式:对于基本数据类型如果是局部变量则保存在栈上面,如果是成员变量则在堆中。对于包装类保存在堆上(成员变量,在不考虑 JIT 优化的栈上分配时,都是随着对象一起保存在堆上的)