【发布时间】:2011-02-19 21:02:21
【问题描述】:
考虑这个(恕我直言简单)示例:
public class DecompilerTest {
public static void main(String[] args) {
Object s1 = "The", s2 = "answer";
doPrint((Object) "You should know:");
for (int i = 0; i < 2; i++) {
doPrint(s1);
doPrint(s2);
s1 = "is";
s2 = new Integer(42);
}
System.out.println();
}
private static void doPrint(String s1) {
System.out.print("Wrong!");
}
private static void doPrint(Object s1) {
System.out.print(s1 + " ");
}
}
在没有调试信息的情况下使用源/目标级别 1.1 编译它(即不应该存在局部变量信息)并尝试反编译它。我尝试了 Jad、JD-GUI 和 Fernflower,它们都至少有一个调用错误(即程序至少打印了一次“错误!”)
真的没有 java 反编译器可以推断出正确的强制转换,从而不会调用错误的重载吗?
编辑: 目标级别 1.1,因此不存在 Java6 特定的快速验证信息。这可能会给反编译器一个线索,即 s1 已被声明为 Object 而不是 String。即使没有这些信息,反编译器也应该能够反编译代码(不一定获得原始变量类型,但表现出相同的行为),特别是因为许多混淆器也会剥离它。
哪些反编译器出错了:
- 他们在第一次通话中错过了
(Object)的演员阵容。 - 他们推断
s1的类型为String,但忘记在对doPrint的调用中添加强制转换(因此调用的是字符串版本而不是对象版本)。 - 一个蹩脚的(我什至没有列出)甚至将
s2的类型推断为字符串,导致代码无法编译。
无论如何,这段代码从不调用String 重载,但反编译的代码却调用了。
【问题讨论】:
-
“他们接错电话”是什么意思?反编译后生成什么源码?
标签: java decompiler jad