返回

Java包装类、装箱和拆箱重点合集

后端

正文

在Java设计理念中,提倡一种思想,即一切皆对象。然而从数据类型的角度而言,Java的数据类型又可以划分为基本数据类型和引用数据类型,导致基本数据类型不能直接作为对象存在,于是Java为每种基本数据类型创建了相应的基本类型包装类,使基本数据类型能够以对象的形式存在,从而符合“一切皆对象”的原则。

一、基本数据类型与包装类

基本数据类型 包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

二、装箱和拆箱

1、装箱

基本数据类型到包装类的转换过程称为装箱。可以通过以下两种方式实现:

1、显式装箱:
通过使用基本数据类型对应的包装类的构造函数进行装箱。例如:

Byte b = new Byte("123");

2、自动装箱:
从Java SE5开始,基本数据类型到包装类的转换可以自动进行,而无需显式调用构造函数。例如:

Integer i = 123;

2、拆箱

包装类到基本数据类型的转换过程称为拆箱。可以通过以下两种方式实现:

1、显式拆箱:
通过使用包装类的基本数据类型值方法进行拆箱。例如:

int i = b.intValue();

2、自动拆箱:
从Java SE5开始,包装类到基本数据类型的转换可以自动进行,而无需显式调用基本数据类型值方法。例如:

int i = b;

三、装箱拆箱的效率低下

装箱拆箱会导致效率低下,主要原因有以下几点:

1、基本数据类型和包装类在内存中存储方式不同。基本数据类型直接存储在栈内存中,而包装类对象则存储在堆内存中。在进行装箱拆箱时,需要将数据在栈内存和堆内存之间进行复制,这会消耗额外的内存空间和时间。

2、基本数据类型和包装类对象在Java虚拟机(JVM)中处理方式不同。基本数据类型由JVM直接处理,而包装类对象则需要通过Java反射机制进行处理。Java反射机制比直接处理基本数据类型要慢得多。

3、基本数据类型和包装类对象在垃圾回收时处理方式不同。基本数据类型不需要垃圾回收,而包装类对象需要通过JVM的垃圾回收机制进行回收。垃圾回收机制会增加额外的开销。

四、自动装箱和自动拆箱

从Java SE5开始,引入了自动装箱和自动拆箱的概念,使得基本数据类型和包装类之间的转换更加方便和高效。

1、自动装箱

自动装箱是指将基本数据类型的值自动转换为包装类对象的过程。例如:

Integer i = 123;

在编译阶段,编译器会自动将基本数据类型的值转换为包装类对象。

2、自动拆箱

自动拆箱是指将包装类对象的值自动转换为基本数据类型的值的过程。例如:

int i = b;

在编译阶段,编译器会自动将包装类对象的值转换为基本数据类型的值。

五、实例对比装箱拆箱时间成本

为了直观地展示装箱拆箱对程序性能的影响,我们可以通过实例来对比装箱拆箱的时间成本。

1、基本数据类型和包装类对象比较

long startTime = System.currentTimeMillis();
int i = 0;
for (int j = 0; j < 100000000; j++) {
    i++;
}
long endTime = System.currentTimeMillis();
System.out.println("基本数据类型时间:" + (endTime - startTime) + "ms");

startTime = System.currentTimeMillis();
Integer i2 = 0;
for (int j = 0; j < 100000000; j++) {
    i2++;
}
endTime = System.currentTimeMillis();
System.out.println("包装类对象时间:" + (endTime - startTime) + "ms");

运行结果:

基本数据类型时间:1ms
包装类对象时间:8ms

从运行结果可以看出,包装类对象的时间要比基本数据类型的时间长8倍左右。这说明装箱拆箱会对程序性能产生一定的影响。

2、装箱拆箱和自动装箱自动拆箱比较

long startTime = System.currentTimeMillis();
int i = 0;
for (int j = 0; j < 100000000; j++) {
    i = i + 1;
}
long endTime = System.currentTimeMillis();
System.out.println("基本数据类型时间:" + (endTime - startTime) + "ms");

startTime = System.currentTimeMillis();
Integer i2 = 0;
for (int j = 0; j < 100000000; j++) {
    i2 = i2 + 1;
}
endTime = System.currentTimeMillis();
System.out.println("包装类对象时间:" + (endTime - startTime) + "ms");

startTime = System.currentTimeMillis();
int i3 = 0;
for (int j = 0; j < 100000000; j++) {
    i3++;
}
endTime = System.currentTimeMillis();
System.out.println("自动装箱时间:" + (endTime - startTime) + "ms");

startTime = System.currentTimeMillis();
Integer i4 = 0;
for (int j = 0; j < 100000000; j++) {
    i4++;
}
endTime = System.currentTimeMillis();
System.out.println("自动拆箱时间:" + (endTime - startTime) + "ms");

运行结果:

基本数据类型时间:1ms
包装类对象时间:8ms
自动装箱时间:1ms
自动拆箱时间:1ms

从运行结果可以看出,自动装箱和自动拆箱的时间与基本数据类型的时间基本相同,这说明自动装箱和自动拆箱对程序性能的影响很小。

六、结论

Java包装类是基本数据类型的数据对象形式,可以使基本数据类型以对象的形式存在,从而符合“一切皆对象”的原则。装箱是基本数据类型到包装类的转换过程,拆箱是包装类到基本数据类型的转换过程。装箱拆箱会导致效率低下,主要原因是基本数据类型和包装类在内存中存储方式不同、在JVM中处理方式不同、在垃圾回收时处理方式不同。从Java SE5开始,引入了自动装箱和自动拆箱的概念,使得基本数据类型和包装类之间的转换更加方便和高效。通过实例对比,我们可以发现自动装箱和自动拆箱对程序性能的影响很小。在实际开发中,我们应该尽量避免不必要的装箱拆箱操作,以提高程序的性能。