【问题标题】:Decompiled Java class producing different output反编译的 Java 类产生不同的输出
【发布时间】:2013-01-18 18:48:48
【问题描述】:

出于好奇,我刚刚使用 DJ Java Decompiler 以及 CAVAJ Java Decompiler 反编译了下面的代码 (Java版本是1.7) 这是正常的源代码:


    byte a = 10;
    a = (byte) (a +1);

    byte b = 10;
    b = b++;

    byte c = 10;
    c +=c;

    System.out.printf("a=%d \t b=%d \t c=%d\n",a,b,c);

显示输出为:a=11 b=10 c=20



这是反编译的:

    byte a = 10;
    a++;
    byte b = 10;
    b++;
    b = b;
    byte c = 10;
    c += c;
    System.out.printf("a= %d \t b = %d \t c = %d\n", new Object[] {
        Byte.valueOf(a), Byte.valueOf(b), Byte.valueOf(c)
    });

作为源代码输出为:a=11 b=11 c=20


更清楚地说,它与byte 无关,int 也发生了同样的事情,我什至在在线编译器 IDEONE 中检查了上述代码,并给出了与我相同的输出。

那么,是反编译器产生了错误的代码还是别的什么??

【问题讨论】:

  • 我不明白在第二种情况下额外的空格是如何从输出中消失的。
  • @dystroy 这可能是 Decompiler 的编辑器格式化代码的功能
  • 这可能应该在 CAVAJ 的论坛中讨论,因为它看起来是一个反编译错误。
  • @Anony-Mousse 我想他担心反编译器将b=b++; 更改为b++;b=b;
  • 是的,看起来像一个 CAVAJ 错误。 这里我们无能为力。

标签: java decompiler


【解决方案1】:

我会给你一个简短的回答:是的,看起来,反编译器产生了错误的代码。 因为这个:

byte b = 10;
b = b++;

强烈预测行为(b 不会改变)。

UPD:此外,没有任何一个反编译器可以100% 保证生成的反编译代码的正确性。

UPD-2:您确定向我们提供您的代码的实际版本吗?因为这个:

byte aa = 10;
a = (byte) (a +1);

当然是一个错误。它甚至不会编译:)

UPD-3 好吧,我需要说,Jad 反编译器(用于 Intel 平台上的 Windows 9x/NT/2000 的 Jad 1.5.8g)产生相同的代码:

    byte b = 10;
    b++;
    b = b;

...

    java.lang.System.out.printf("a=%d \t b=%d \t c=%d\n", new java.lang.Object[] {...

但是这并不奇怪:Cavaj Java 反编译器使用 Jad 作为其 Java 反编译引擎

结论:将此行为视为Jad 反编译器的功能/错误,这远非完美。

【讨论】:

  • 等10分钟,我自己查一下:)
  • @dystroy 不,它们属于同一类。顺便说一句,是什么让你这么认为
  • @sansix 请查看我的 UPD-2,您的代码中有一些错误。
  • @dystroy 也是你的信息:我检查了这个案例,确实是 Jad 的缺陷。
  • 另一方面,他们可能会解释说他们的反编译器帮助 OP 在他的代码中找到了一个错误......
【解决方案2】:

这与反编译器无关。当您使用 java 编译器编译代码时,在某些情况下,编译器会更改您的代码并将其优化为另一个不会更改结果的代码。你的代码是:

byte a = 10;
a = (byte) (a + 1);

在这种情况下,java 编译器知道不需要在字节和字节之间进行类型转换,因此,编译器会尝试删除您的类型转换,并且在此过程中,它会用它可以理解的最接近的代码替换您的代码.这是编译器的输出:

byte a = 10;
a++;

所以,这与反编译过程无关。 java 编译器会改变你的代码。

【讨论】:

  • 所以你的意思是说a = (byte) (a + 1);这里不需要类型转换?
  • 亲爱的,我们正在谈论这个:b = b++;
  • 答案是一样的。 b = b++; 编译过程中的更改不会反编译。此代码将替换为b++;,是的,不需要类型转换。
  • 当您编写像byte a = 0; a = (byte) (a + 1); 这样的代码时,编译器知道您正在尝试执行a++;,它会更改您的代码并在您的版本中将其优化为a++;,需要进行类型转换但在编译版本不是必需的,结果是一样的。然后只需编译器将您的代码更改为优化版本。
  • @SasanYavari 用b++; b = b; 替换b = b++; 不是优化。
猜你喜欢
  • 2013-09-13
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 2017-08-05
  • 2014-05-06
  • 2014-08-24
  • 1970-01-01
  • 2014-04-02
相关资源
最近更新 更多