【发布时间】:2020-10-02 01:34:02
【问题描述】:
考虑以下类:
class Temp {
private final int field = 5;
int sum() {
return 1 + this.field;
}
}
然后我编译和反编译这个类:
> javac --version
javac 11.0.5
> javac Temp.java
> javap -v Temp.class
...
int sum();
descriptor: ()I
flags: (0x0000)
Code:
stack=2, locals=1, args_size=1
0: iconst_1
1: aload_0
2: invokestatic #3 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
5: pop
6: iconst_5
7: iadd
8: ireturn
简单来说,javac 将sum() 编译为:
int sum() {
final int n = 1;
Objects.requireNonNull(this); // <---
return n + 5;
}
Objects.requireNonNull(this) 在这里做什么?重点是什么?这是否与可达性有关?
Java 8 编译器类似。它插入this.getClass() 而不是Objects.requireNonNull(this):
int sum() {
final int n = 1;
this.getClass(); // <---
return n + 5;
}
我也尝试用 Eclipse 编译它。它不插入requireNonNull:
int sum() {
return 1 + 5;
}
所以这是 javac 特有的行为。
【问题讨论】:
-
似乎,它没有意识到与其他表达式相比,
this没有必要这样做。 -
好收获(+1)。除此之外,
javac 15-ea也可以观察到相同的行为。进一步观察,删除final工作正常。 -
试图放入评论中,
int sum();... Code: stack=2, locals=1, args_size=1 0: iconst_1 1: aload_0 2: invokestatic #13 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object; 5: pop 6: iconst_5 7: iadd 8: ireturn与删除解析为int sum();... Code: stack=2, locals=1, args_size=1 0: iconst_1 1: aload_0 2: getfield #7 // Field field:I 5: iadd 6: ireturn的最终关键字时相比
标签: java java-8 javac java-11 ecj