反编译的Java类产生不同的输出

时间:2013-01-18 18:48:48

标签: java decompiler

出于好奇,我只使用 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中的上述代码,并提供与我相同的输出

那么,反编译器是否产生了错误的代码或者是其他东西?

2 个答案:

答案 0 :(得分:4)

我会给你一个简短的回答:是的,好像,反编译器正在生成错误的代码。 因为这一个:

byte b = 10;
b = b++;

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

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

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

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

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

UPD-3 好吧,我需要说,Jad反编译器(英特尔平台上的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反编译器的功能/错误,这远非完美。

答案 1 :(得分:-2)

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

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

在这种情况下,java编译器知道不需要在字节和字节之间键入强制类型,因此,编译器会尝试删除你的类型转换,并且在此过程中,它会用最接近的代码替换你的代码。 。这是编译器输出:

byte a = 10;
a++;

所以,这不是关于反编译过程。 java编译器会更改您的代码。