We don’t allow questions seeking recommendations for software libraries, tutorials, tools, books, or other off-site resources. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(5)
你好,mihi,
很抱歉回复晚了。我正在复制我的答案 http://www.reversed-java.com/ fernflower/forum?threadfolder=2_DE
您的问题实际上是一个众所周知的问题。让我们看看:
1)纯字节码不包含任何有关对象变量类型的信息,因此在第一遍中 s1 和 s2 被声明为 Object。
2) 反编译器正在努力为每个变量分配最好的可能类型(= Fernflower 中实现的“最窄类型原则”)。因此 s1 和 s2 被正确识别为 String 的实例。
3) 调用 doPrint 为我们提供了正确方法的直接链接
private static void doPrint(Object s1)
4) 到目前为止一切正常,对吗?现在我们有一个字符串变量 s1 传递给一个函数,该函数需要一个对象。我们需要投射它吗?您可能会认为并非如此,因为 Object 是 String 的超类型。但我们确实这样做了 - 因为同一个类中还有另一个函数具有相同的名称和不同的参数签名。所以我们需要分析整个类来确定是否需要强制转换。
5) 一般来说,这意味着我们需要分析所有库中所有引用的类,包括java运行时。工作量巨大!事实上,此功能已在 Fernflower 的某些 alpha 版本中实现,但由于性能和内存损失,尚未在生产中实现。其他提到的反编译器在设计上就缺乏这种能力。
希望我已经澄清了一些事情:)
Hallo mihi,
sorry for the late response. I'm copying my answer from http://www.reversed-java.com/fernflower/forum?threadfolder=2_DE
Your problem is actually a well known one. Let's see:
1) Pure bytecode doesn't contain any information about the type of object variables, so in the first pass s1 and s2 are declared as Object.
2) Decompiler is trying hard to assign the best possible type to each variable (= "narrowest type principle" implemented in Fernflower). So s1 and s2 are correctly identified as instances of String.
3) Invocation of doPrint give us a direct link to the correct method
private static void doPrint(Object s1)
4) Everything OK so far, right? Now we have got a String variable s1 passed to a function, which expects an Object. Do we need to cast it? Not as such, you would think, as Object is a super-type of String. And yet we do - because there is another function within the same class with the same name and a different parameter signature. So we need to analyse the whole class to find out, whether a cast is needed or not.
5) Generally speaking, it means we need to analyse ALL referenced classes in ALL libraries including the java runtime. A huge load of work! Indeed, this feature was implemented in some alpha version of Fernflower, but have not made it in the production yet because of performance and memory penalty. Other mentioned decompilers lack this ability by design.
Hope I have clarified things a bit :)
Krakatau 正确处理所有重载方法,甚至是基本类型上重载的方法,而大多数反编译器都会出错。它总是将参数转换为被调用方法的确切类型,因此代码可能比必要的更混乱,但至少它是正确的。
披露:我是《喀拉喀托》的作者。
Krakatau correctly handles all overloaded methods, even methods overloaded on primitive types, which most decompilers get wrong. It always casts arguments to the exact type of the called method, so the code may be more cluttered than necessary, but at least it is correct.
Disclosure: I am the author of Krakatau.
用于反编译的 JadClipse Eclipse 插件还提供了 JODE 反编译器,您可能想尝试一下。当贾德放弃时我会使用它。
Dava 反编译器还使用 Soot,我上次查看时,它在重建原始 Java 代码方面非常雄心勃勃。我没有尝试过你的例子,但你可能想看看。 http://www.sable.mcgill.ca/dava/
The JadClipse Eclipse plugin for decompiling also provides the JODE decompiler, which you may want to try. I use it when Jad gives up.
Also the Dava decompiler uses Soot which - last time i looked - was very ambitious in reconstructing the original Java code. I have not tried with your example, but you may want to have a look. http://www.sable.mcgill.ca/dava/
Procyon 应正确处理重载方法调用。与 Krakatau 一样,Procyon 最初会为与目标方法不完全匹配的每个方法参数插入强制转换。然而,其中大部分将在反编译的后期阶段被删除,该阶段会识别并消除冗余的强制转换。仅当 Procyon 可以验证这样做不会导致调用绑定到不同的方法时,它才会删除调用参数上的强制转换。例如,如果声明该方法的
.class
无法解析,它根本不会尝试删除强制转换,因为它无法知道哪些重载可能会发生冲突。Procyon should handle overloaded method invocations correctly. Like Krakatau, Procyon initially inserts casts for every method argument that doesn't exactly match the target method. However, most of these will be removed during a later phase of decompilation that identifies and eliminates redundant casts. Procyon will only remove casts on call arguments if it can verify that doing so will not result in the call binding to a different method. For example, if the
.class
declaring the method cannot be resolved, it won't attempt to remove the casts at all, because it has no way of knowing what overloads might conflict.补充一下之前的答案:
以下是截至 2015 年 3 月的现代反编译器列表:
所有这些都支持重载方法。
您可以在线测试上述反编译器,无需安装并做出您自己的明智选择。
云中的 Java 反编译器:http://www.javadecompilers.com/
Adding to the previous answers:
Here's a list of modern decompilers as of March 2015:
ALL of them support overloaded methods.
You may test above mention decompilers online, no installation required and make your own educated choice.
Java decompilers in the cloud: http://www.javadecompilers.com/