Java 1.5 引入了一种特殊功能,即将原始类型自动转换为相应的包装器类,反之亦然。
自动装箱 :将原始类型自动转换为相应包装类的对象称为自动装箱。例如 – 将int
转换为Integer
,将long
转换为Long
,将double
转换为Double
等。
拆箱:这只是自动装箱的逆过程。自动将包装类的对象转换为其对应的原始类型类型称为拆箱。例如 – 将Integer
转换为int
,Long
转换为long
,将Double
转换为double
等。
Primitive type Wrapper class
boolean Boolean
byte Byte
char Character
float Float
int Integer
long Long
short Short
double Double
Java 中什么时候发生自动装箱和拆箱
自动装箱
让我们看一些带有示例的案例,其中发生了自动装箱。
案例 1 :当一个方法期望一个包装器类对象但是作为参数传递的值是一个基本类型。例如,在下面的代码中,方法myMethod()
期望一个Integer
包装类的对象,但是我们传递了一个原始的int
类型。程序运行正常,因为编译器执行自动装箱(将int
转换为Integer
)
class AutoboxingExample1
{
public static void myMethod(Integer num){
System.out.println(num);
}
public static void main(String[] args) {
/* passed int (primitive type), it would be
* converted to Integer object at Runtime
*/
myMethod(2);
}
}
输出:
2
案例 2 :在某个时间点,您将原始类型值分配给其包装类的对象。例如:以下语句有效,因为编译器在运行时执行自动装箱。
Integer inum = 3; //Assigning int to Integer: Autoboxing
Long lnum = 32L; //Assigning long to Long: Autoboxing
案例 3 :处理集合框架类时:
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(11); //Autoboxing - int primitive to Integer
arrayList.add(22); //Autoboxing
这里ArrayList
类需要一个Integer
包装类对象,但是我们提供了int
原始类型。
拆箱
案例 1 :方法期待Integer
对象(参数)但我们提供了int
。发生了将Integer
转换为int
的自动转换(拆箱)。
class UnboxingExample1
{
public static void myMethod(int num){
System.out.println(num);
}
public static void main(String[] args) {
Integer inum = new Integer(100);
/* passed Integer wrapper class object, it
* would be converted to int primitive type
* at Runtime
*/
myMethod(inum);
}
}
输出:
100
案例 2 :作业
Integer inum = new Integer(5);
int num = inum; //unboxing object to primitive conversion
案例 3 :在处理集合类时:
ArrayList arrayList = new ArrayList()
int num = arrayList.get(0); // unboxing because get method returns an Integer object
幕后发生了什么?
在上一节中,我们学习了 java 编译器如何在基本类型和相应的包装器对象之间执行自动转换。让我们讨论一下编译器在自动装箱和拆箱过程中实际做了什么。理解这一点的最好方法是比较 java 1.5 之前和 java 1.5 之后的事情(java 1.5 中引入的装箱和拆箱)。
自动装箱 :
我们看到了什么:
Integer number = 100;
编译器做了什么(或者我们以前在 java 1.5 之前做过的事情):
Integer number = Integer.valueOf(100);
拆箱:
我们看到了什么:
Integer num2 = new Integer(50);
int inum = num2;
编译器做什么:
Integer num2 = new Integer(50);
int inum = num2.intValue();
类似的事情发生在其他包装类和原始类型,如long
,double
,short
等。
你应该注意的事情很少:
在进行比较时不要混合原始类型和对象。对于这样的比较,您可能会得到不可预测的结果。更好的做法是:将对象与对象进行比较(使用equals()
方法)并将原始类型与原始类型进行比较(使用逻辑运算符,如==
,<
等)。