目录
1、Java中的自动装箱
2、Java中的自动拆箱
3、自动装箱和拆箱总结
4、在Java中怎样避免自动装箱和拆箱?
1、Java中的自动装箱
自动装箱是 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 值作为基本类型而不是 Integer 对象添加到 li 列表,但是代码仍然可以编译。这里 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)); //装箱
}
在以下情况下,Java 编译器会对基本类型的值进行自动装箱:
- 把基本类型的值作为参数传递给需要相应包装类的对象的方法。
- 把基本类型的值赋给相应包装类的变量。
2、Java中的自动拆箱
接下来,思考一下下边的方法:
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() 方法时,Java 会将 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)称为拆箱。在以下情况下,Java 编译器会对包装类型的值进行自动拆箱:
- 把包装类型的值作为参数传递给需要相应基本类型的值的方法。
- 把包装类型的值赋值给相应基本类型的变量。
下边的例子展示了拆箱是如何工作的:
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("absolute value of " + 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;
}
}
该程序会打印以下内容:
absolute value of -8 = 8
pi = 3.1416
3、自动装箱和拆箱总结
自动装箱和拆箱可以让开发人员编写更加清晰的代码,使代码更加易于阅读。下表列出了基本类型及其对应的包装类,Java 编译器会使用它们进行自动的装箱和拆箱:
基本类型 | 包装类型 |
boolean | Boolean |
byte | Byte |
char | Character |
float | Float |
int | Integer |
long | Long |
short | Short |
double | Double |
自动装箱和拆箱的实现是通过 Java 编译器在编译时进行的。具体来说,Java 编译器会将自动装箱和拆箱操作转换为对应的方法调用,以实现基本数据类型和包装类型之间的转换。
但这在性能方面是要付出代价的。装箱后的值本质上就是把原始类型包裹起来,并保存在堆里。因此,装箱后的值需要更多的内存,并需要额外的内存搜索来获取被包裹的原始值。//尽量避免不必要的装箱
4、在Java中怎样避免自动装箱和拆箱?
(1)使用基本数据类型
尽可能地使用基本数据类型,而不是对应的包装类型。基本数据类型的数据存储在栈中,而包装类型的对象存储在堆中,因此基本数据类型的操作比包装类型的操作更加高效。
(2)使用静态常量
对于常用的数值,可以使用静态常量来避免自动装箱的开销。例如,使用如下代码定义一个静态常量:
public static final int MAX_VALUE = 100;
这样就可以在代码中直接使用 MAX_VALUE,而不需要使用 Integer.valueOf(MAX_VALUE)。文章来源:https://www.toymoban.com/news/detail-492689.html
通过上述方法,可以有效地避免自动装箱和拆箱对程序性能的影响。文章来源地址https://www.toymoban.com/news/detail-492689.html
到了这里,关于Java 中的自动装箱和拆箱详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!