这些Java教程是针对JDK 8编写的。本页中描述的示例和实践不利用后续版本中引入的改进,可能使用不再可用的技术。
请参阅Java语言更改,了解Java SE 9及后续版本中更新的语言特性的摘要。
请参阅JDK发行说明,了解所有JDK版本的新功能、增强功能以及已删除或弃用选项的信息。
自动装箱是Java编译器在原始类型和它们对应的对象包装类之间进行的自动转换。例如,将一个int转换为Integer,将一个double转换为Double等等。如果转换反过来进行,这被称为拆箱。
下面是自动装箱的最简单示例:
Character ch = 'a';
本节中的其余示例都使用了泛型。如果您还不熟悉泛型的语法,请参阅泛型(已更新)教程。
考虑以下代码:
List<Integer> li = new ArrayList<>(); for (int i = 1; i < 50; i += 2) li.add(i);
尽管您将int值作为原始类型添加到li中,而不是Integer对象,但代码仍然能够编译。因为li是一个Integer对象的列表,而不是int值的列表,所以您可能会想为什么Java编译器不会在编译时生成错误。编译器之所以不会生成错误,是因为它会将i转换为一个Integer对象,并将该对象添加到li中。因此,编译器在运行时将上述代码转换为以下代码:
List<Integer> li = new ArrayList<>(); for (int i = 1; i < 50; i += 2) li.add(Integer.valueOf(i));
将一个原始值(例如int)转换为相应包装类(Integer)的对象称为自动装箱。当原始值:
考虑以下方法:
public static int sumEven(List<Integer> li) { int sum = 0; for (Integer i: li) if (i % 2 == 0) sum += i; return sum; }
因为取余(%)和一元加(+=)运算符不适用于Integer对象,您可能会想为什么Java编译器在不生成任何错误的情况下编译该方法。编译器之所以不会生成错误,是因为它会在运行时调用intValue方法将Integer转换为int:
public static int sumEven(List<Integer> li) { int sum = 0; for (Integer i : li) if (i.intValue() % 2 == 0) sum += i.intValue(); return sum; }
将包装类的对象(Integer)转换为相应基本类型(int)的值称为拆箱。当包装类的对象:
Unboxing
示例展示了它的工作原理:
import java.util.ArrayList; import java.util.List; public class Unboxing { public static void main(String[] args) { Integer i = new Integer(-8); // 1. 方法调用中的拆箱 int absVal = absoluteValue(i); System.out.println(i + "的绝对值 = " + absVal); List<Double> ld = new ArrayList<>(); ld.add(3.1416); // Π 通过方法调用进行装箱 // 2. 赋值中的拆箱 double pi = ld.get(0); System.out.println("pi = " + pi); } public static int absoluteValue(int i) { return (i < 0) ? -i : i; } }
程序打印以下内容:
-8的绝对值 = 8 pi = 3.1416
自动装箱和拆箱让开发人员能够编写更清晰的代码,使其更易于阅读。下表列出了原始类型及其相应的包装类,这些包装类由Java编译器用于自动装箱和拆箱:
原始类型 | 包装类 |
---|---|
boolean | Boolean |
byte | Byte |
char | Character |
float | Float |
int | Integer |
long | Long |
short | Short |
double | Double |