Java 自动装箱和数学表达式?
Java autoboxing and mathematical expressions?
我认为当我阅读 Joshua Bloch 的 Effective Java 时,我的印象是出于性能原因应该避免自动装箱。但是我得到的信息相互矛盾,我可以相信编译器在我进行隐式转换时会以最佳方式使用 valueOf()
和 intValue()
。
所以我在下面编写了这段代码
Integer capacity = 50103;
Integer inventory = 40122;
int available = capacity - inventory;
理论上将编译为与以下代码相同的字节码。
Integer capacity = Integer.valueOf(50103);
Integer inventory = Integer.valueOf(40122);
int available = capacity.intValue() – inventory.intValue();
从 Java 7 和 8 开始,这是真的吗?是否有任何理由显式 box/unbox 或编译器现在会为此进行优化?
这不是优化,它只是相同的代码,编写不同但编译为相同的字节码。
具有以下内容:
Integer capacity = 50103;
Integer inventory = 40122;
int available = capacity - inventory;
两个整数值首先装箱到 Integer
中。然后将它们拆箱到 int
以执行减法。这完全等同于第二段代码。
在这些情况下,没有特别的理由明确地框出值。最好让编译器这样做,因为它提供了更短、更易读的代码。
这是您的第一个示例生成的字节码 (JDK 1.8.0_60):
0: ldc #2 // int 50103
2: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: ldc #4 // int 40122
8: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
11: astore_2
12: aload_1
13: invokevirtual #5 // Method java/lang/Integer.intValue:()I
16: aload_2
17: invokevirtual #5 // Method java/lang/Integer.intValue:()I
20: isub
21: istore_3
22: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
25: iload_3
26: invokevirtual #7 // Method java/io/PrintStream.println:(I)V
29: return
您可以清楚地看到第一个代码段与第二个代码段的编译结果相同。
that autoboxing should be avoided for performance reasons
这只是意味着装箱和拆箱会产生开销,不应不必要地执行。
boxing/unboxing是隐式执行还是显式执行都没有关系;它以任何一种方式编译为相同的字节码。
我认为当我阅读 Joshua Bloch 的 Effective Java 时,我的印象是出于性能原因应该避免自动装箱。但是我得到的信息相互矛盾,我可以相信编译器在我进行隐式转换时会以最佳方式使用 valueOf()
和 intValue()
。
所以我在下面编写了这段代码
Integer capacity = 50103;
Integer inventory = 40122;
int available = capacity - inventory;
理论上将编译为与以下代码相同的字节码。
Integer capacity = Integer.valueOf(50103);
Integer inventory = Integer.valueOf(40122);
int available = capacity.intValue() – inventory.intValue();
从 Java 7 和 8 开始,这是真的吗?是否有任何理由显式 box/unbox 或编译器现在会为此进行优化?
这不是优化,它只是相同的代码,编写不同但编译为相同的字节码。
具有以下内容:
Integer capacity = 50103;
Integer inventory = 40122;
int available = capacity - inventory;
两个整数值首先装箱到 Integer
中。然后将它们拆箱到 int
以执行减法。这完全等同于第二段代码。
在这些情况下,没有特别的理由明确地框出值。最好让编译器这样做,因为它提供了更短、更易读的代码。
这是您的第一个示例生成的字节码 (JDK 1.8.0_60):
0: ldc #2 // int 50103
2: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: ldc #4 // int 40122
8: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
11: astore_2
12: aload_1
13: invokevirtual #5 // Method java/lang/Integer.intValue:()I
16: aload_2
17: invokevirtual #5 // Method java/lang/Integer.intValue:()I
20: isub
21: istore_3
22: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
25: iload_3
26: invokevirtual #7 // Method java/io/PrintStream.println:(I)V
29: return
您可以清楚地看到第一个代码段与第二个代码段的编译结果相同。
that autoboxing should be avoided for performance reasons
这只是意味着装箱和拆箱会产生开销,不应不必要地执行。
boxing/unboxing是隐式执行还是显式执行都没有关系;它以任何一种方式编译为相同的字节码。