【发布时间】:2013-03-25 11:13:48
【问题描述】:
我一直试图弄清楚 Java 优化的所有内容,发现了一些有趣的东西。
第一种情况:原始类型编译时优化
public class Clazz {
public static void main(String args[]) {
final int i = 300;
new Clazz() {
void foo() {
System.out.println(i);
}
}.foo();
}
}
编译后(我用jd-gui-0.3.5.windows反编译二进制文件)是这样的:
public class Clazz {
public static void main(String[] args) {
int i = 300;
new Clazz() {
void foo() {
System.out.println(300);
}
}.foo();
}
}
正如预期的那样,不是吗? i 在编译后被替换为它的值(内联优化)。所以,我希望在用它的包装器替换原始类型后看到类似的东西,但是......
第二种情况:非原始类型编译时优化
public class Clazz {
public static void main(String args[]) {
final Integer i = 300; // replaced int with Integer
new Clazz() {
void foo() {
System.out.println(i);
}
}.foo();
}
}
编译后:
public class Clazz {
public static void main(String[] args) {
Integer i = Integer.valueOf(300);
new Clazz() {
void foo() {
System.out.println(Clazz.this);
}
}.foo();
}
}
问题:
在这种情况下Clazz.this 是什么?我知道,它引用了Clazz 的封闭实例,但在这种情况下它不应该工作!我需要打印i,但编译器建议我打印Clazz.this 而不是它,它可以工作!问题是什么? jd-gui 是否会错误地反编译或者我是否遗漏了一些关于 Java 编译和优化的内容?
UPD:
Class$1的内容:
class Clazz$1 extends Clazz {
Clazz$1(Integer paramInteger) {}
void foo() {
System.out.println(this.val$i);
}
}
【问题讨论】:
-
能把
Clazz$1的反编译码也放上来吗?这可能是System.out.println(Clazz.this)的线索。因为Clazz$1可能包含返回i的toString()方法 -
请把
clazz$1的代码也放上来。! -
@VishalK jd-gui 不会单独显示匿名类,它会将其重新包含在封闭类中。
-
@assylias 实际上显示了
-
@zvzdhk 啊我明白了——我直接查看生成的 jar,在这种情况下 jd-gui 重新注入匿名类——如果你直接查看类文件,你就会得到你发布的内容。跨度>
标签: java optimization compilation