我们为什么需要包装类、自动装箱与自动拆箱?
Java是一种面向对象的语言,但也存在非面向对象的部分,如:基本数据类型。当我们使用基本数据类型时,它们并不是面向对象的,而我们希望它们具有对象的特性以便操作时,该怎么办呢?
为了解决这个问题,Java设计并提供了八个类,对应八个基本数据类型,我们就称这八个类包装类。
既然是数据,就涉及到数据转换的问题,基本数据类型如何与包装类类型进行转换呢?这就需要用到“装箱”与“拆箱”操作了。
包装类
包装类位于java.lang包中,八个基本数据类型与其包装类对应关系如下:
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
自动装箱与自动拆箱
装箱
把基本数据类型变成包装类,称为,装箱操作。实例:
int num = 10;
Integer num1 = new Integer(num);
Integer num2 = Integer.valueOf(num); // 两种方法均可
拆箱
把包装类的对象,转换为对应的基本数据类型,称为,拆箱操作。实例:
Integer num = new Integer(10);
int num1 = num.intValue();
double num2 = num.doubleValue();
valueOf
在装箱时,我们可以使用valueOf方法,这个方法有点特别,特别点就在它的缓存设计,在缓存范围内(-128至127),下一次使用时,会直接返回已缓存的地址。
实例:
public class Test {
public static void main(String[] args) {
Integer num1 = Integer.valueOf(10);
Integer num2 = Integer.valueOf(10);
System.out.println( num1 == num2 );
Integer num3 = Integer.valueOf(1000);
Integer num4 = Integer.valueOf(1000);
System.out.println( num3 == num4 );
}
}
----------------------------------------------
输出结果为:
true
false
我们可以通过查看valueOf的源码,进一步了解valueOf缓存的实现:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
自动装箱
可以直接把一个基本数据类型的值,赋值给包装类,就称为自动装箱。
把基本数据类型可以直接赋值给包装类,实例:
Integer num1 = 10;
在执行时,编译器会编译成:
Integer num1 = Integer.valueOf(10);
自动拆箱
可以直接把一个包装类的对象,赋值给基本数据类型的变量,就称为自动拆箱。
把包装类直接赋值给基本数据类型,实例:
Integer num1 = 10;
int num2 = num1;
在执行时,编译器会编译成:
Integer num1 = 10;
int num2 = num1.intValue();
基本数据类型与包装类的区别
我总结出主要有以下三点区别:
- 1.默认值不同。基本数据类型,如int,默认值是0。包装类类型,如Integer,默认值则为null。
- 2.包装类相比基本类,提供了许多方法供直接使用。
- 3.在集合中,不能存放基本数据类型,只能存对象。所以在类当中,一般使用包装类,在方法当中,一般使用基本数据类型。