2

I am trying to understand how Java compiler works by de-compiling the .class files. I have used the Java decompiler (http://jd.benow.ca/) and showmycode (http://www.showmycode.com/) They show me different sourcecode in .java file. Why? Which should I trust.

.java file

class HelloWorld{
    public static void main(String[] args){
        System.out.println("Hello, World!");
    }
}

.class file as de-compiled by java decompiler:

import java.io.PrintStream;

class HelloWorld
{
  public static void main(String[] paramArrayOfString)
  {
    System.out.println("Hello, World!");
  }
}

.class file as de-compiled by showmycode

import java.io.PrintStream;
class HelloWorld {
   HelloWorld() {
   } 
   public static void main(string args[]) 
   {
       system.out.println("Hello, World!"); 
   }
}
2
  • 2
    a decompiler makes code that tried to do the same thing as the original, it doesn't re-produce the exact original code. if i can only tell that three numbers add up to 10, it makes little difference if i use [2,4,4], [1,2,7], or [3,4,3] to get there; they all produce the same output as whatever the original formula did when executed. Commented Dec 22, 2014 at 6:12
  • 2
    If you want to understand how the compiler works, use a disassembler to look at the actual bytecode generated. And ideally, don't use javap, since it hides stuff. Commented Dec 22, 2014 at 6:39

2 Answers 2

8

A decompiler cannot recreate the original source code, it can only create a new source code which would compile into the same binary as the original source code.

(Assuming that showmycode will fix their case issues, see below) The three source codes - the original one, the one created by java decompiler and the one created by showmycode are idempotent. They are written in different ways but do exactly the same thing. Both decompilers are right.

Here's the differences explained:

  • Constructor present / absent: Every class has a constructor. If the programmer does not supply a constructor, the compiler will generate one. A smart decompiler will recognize this and assume for a constructor which is empty that it was generated and thus omit it from the decompiled source code.
  • Position of [] for arrays: The declarations String[] foo and String foo[] are the same. I recommend to always go for String[] foo, because in Java (as opposed to C), being an array is an attribute of the type, not the variable.
  • Formatting / placement of {}, indentation etc.: doesn't matter at all, mostly. It might matter a little bit for the debug information (line numbers of stack traces), but that's not part of the significant behavior of the code, which is what we'd be interested in.
  • Names of automatic variables (local variables incl. parameter variables) are not available in the binary, so the decompiler has to invent new names when decompiling.

Note that showmycode seems to have an issue with case of type names. Java is case sensitive, and it must be System and String, not system and string. Seems like showmycode gets this wrong, which means that code cannot be compiled again unless you manually fix all these type names.

Another issue of showmycode is how it deals with varargs methods. I changed the signature of main to public static void main(String... args) to see what I get, and I got public static transient void main(string args[]), which doesn't compile. Nowadays a decompiler is expected to produce correct, compilable source code, and showmycode doesn't.

Sign up to request clarification or add additional context in comments.

2 Comments

Actually I have pasted the showmycode code exactly as it shows. It does say string instead of String and system instead of System.
In that case, scrap showmycode, Java is case sensitive.
0

Because there are several different ways to write most statements, that all boil down to the same object code. There is in general no single correct decompilation.

5 Comments

This is low quality answer. Same explanation was provided as a comment by @dandavis already before
@xmojmr Non sequitur. The fact that other people provided the same information in their comments and answers isn't an indication of low quality in this one. Rather it indicates agreement as to what the answer is.
In my opinion argumenting in Latin does not make your answer better. Your answer adds nothing new to what was already said. Claim without any proofs, evidence or links to supporting facts. Using "cooking" metaphor and misleading terms ("object code") is not helping as well. Vague single line answers may be good for reputation hunting but they usually belong to the comment part of a question
@xmojmr Once agin you've missed the point. In my opinion this answer doesn't need to be made better. If your idea of a low quality answer includes correct answers, I suggest it stands in need of revision. The use of metaphor doesn't invalidate an answer, and the fact that others have stated the same thing at roughly the same time doesn't invalidate it either. The Latin has been used for thousand of years as the shortest possible way of conveying that your inferences are invalid.
you've missed my point (If I leave out that there are not several ways to write single function call with single literal as argument and that you did not answer the "Which should I trust" part of OP's question). Although your opinion and observation may be correct and we don't care about science but only about engineering, composing Q&A knowledge base out of "believe me" axioms is not useful. You can do better.. I'm saying that after your suggested revision. De omnibus est dubitandum. Vita humana brevis est

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.