この(IMHOの単純な)例を考えてみましょう。
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を試しましたが、いずれも少なくとも1つの呼び出しが間違っていました(つまり、プログラムが少なくとも1回は「Wrong!」と出力しました)。
間違ったオーバーロードを呼び出さないように正しいキャストを推測できるJavaデコンパイラーは本当にありませんか?
編集:ターゲットレベル1.1で、Java6固有の高速検証情報が存在しないようにします。Object
これにより、逆コンパイラーに、s1がとしてではなくとして宣言されているという手がかりが得られる可能性がありString
ます。逆コンパイラーは、この情報がなくてもコードを逆コンパイルできるはずです(必ずしも元の変数タイプを取得する必要はありませんが、同じ動作を示します)。特に、多くの難読化ツールがコードを削除するためです。
逆コンパイラが間違っていたもの:
- 彼ら
(Object)
は最初の電話でキャストを逃した。 - 彼らはのタイプを推測しました
s1
がString
、への呼び出しにキャストを追加するのを忘れていましたdoPrint
(オブジェクトバージョンの代わりに文字列バージョンが呼び出されるように)。 - 1つのくだらないもの(私はリストしていません)は、タイプ
s2
が文字列であると推測し、コンパイルできないコードを引き起こします。
いずれにせよ、このコードはString
オーバーロードを呼び出すことはありませんが、逆コンパイルされたコードは呼び出しました。