能够处理Java 5(包括枚举等新特性)的Java反编译器。

8

我知道这个问题已经被问了无数次了,但是我特别需要一个能够正确处理枚举类型(因为我正在反编译的jar包中使用了很多枚举)的反编译器。我测试了JAD和JD-GUI,它们都不能正确处理。

有人能推荐一个反编译器吗?最好能在Linux下工作,并且可以轻松处理整个jar包而不需要我编写shell脚本。

编辑: 具体来说,我遇到了这样的问题:

switch(myEnum) {
case A: ...
case B: ...
}

它们被反编译(无论是JAD还是JD-GUI)后,通常会呈现出以下样式:

switch ($SWITCH_TABLE$com$MyType()[myEnum.ordinal()]) {
case 1:
case 2:
}

其中$SWITCH_TABLE$com$MyType()要么未声明,要么编译错误。


1
根据我上面链接的问题,http://java.decompiler.free.fr/ 是Java 5的最佳反编译器。如果这对您没有帮助,请告诉我们它为什么没有帮助。 - Joachim Sauer
我不知道JD-GUI,但我们正在使用JD-Eclipse,它使用比JD-GUI更旧的JD-Core版本,并且它也可以处理枚举。 - Thomas
3
毫无疑问,Java 5已经不再是“新的”版本了。 - sehe
1
@Grzenio:请定义“没有工作”。你能举个例子说明它为什么不起作用吗?除非你能告诉我们什么对你不起作用,否则这个问题并不比其他成百上千个重复的问题更好。 - Joachim Sauer
@sehe,我非常同意你的观点。 - Grzenio
显示剩余6条评论
2个回答

2
我发现研究项目的产物CFR特别擅长处理枚举类型。
截至目前,JD-GUI和JAD的表现并不比问题发布时更好,而CFR 0.43版本可以生成正确、可编译的源代码,即使输入的是混淆过的类。

2
无法正确反编译枚举开关。Java类文件在编译后不知道枚举类型,因此您的反编译器无法像您想要的那样对其进行反编译。
枚举类型都是java.lang.Enum的子类型,每个枚举常量都有一个用于switch语句的序数。编译器在该int值上执行switch操作,枚举类型的switch只是一种语法糖。如果您尝试在null枚举上执行switch,则会得到NPE。

取决于反编译器的智能程度。如果它能够找到枚举的声明,那么它应该能够将序数映射回名称。 - Grzenio
如果我反编译一个使用ENUM开关的$1版本类文件,我会得到所有序数以及ENUM常量的列表。这是可以反编译的 - 只需要编码即可。不幸的是,JD-Java反编译器似乎不是开源的 :-( 而JAD太老了,需要付出很大的努力才能跟上其他技术的步伐。 - mjaggard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接