Reputation: 4779
Given the same major version, say Java 7, do different Java Compilers (e.g., Oracle's hotspot, JRockit, or IBM's J9 etc...) compile a given java source code file into the same bytcode?
Scanning the Java 7 language spec it would seem that what is being discussed is the semantics of the language and not the transformation of the code into bytecode.
This question is not the same as do different major.minor versions for a given vendor produce the same bytecode. That question is already answered here - with a could be.
From the following answer to Is the creation of Java class files deterministic? and a comment to that answer that refers to this along side two answers to the major.minor question above 1 and 2, I gather that the answer to my question is YES.
Excerpts for the above are:
The JLS leaves many implementation details to vary from one implementation to another.
and
However the JLS does not specify a 1:1 mapping from source code to the generated byte code, so you should not rely on the exact same byte code to be generated.
Yet a comment here implies differently:
It’s the compiler, i.e. javac, creating the code using a BLAH BLAH BLAH. This has nothing to do with HotSpot.
It implies that given a code X all javac implementations (same version/different vendors) must produce the same Y bytecode.
I cannot see how that is so, but I am unable to verify that it is not (or that what I think, see above) is correct.
Can a definitive answer be given?
Upvotes: 6
Views: 2578
Reputation: 36339
There are 2 questions:
The answer to 1 is yes, obviously. For, otherwise, the JLS had to fully specify the bytecode to generate for each and every language construct. But it doesn't.
The answer to 2 I don't know for sure, though I have heard that eclipse compiler generates slightly different code than javac in some cases. Should be easy to verify.
Upvotes: 2
Reputation: 298163
There are differences between the compilers and interestingly some of the permitted differences led to problems in the past.
Some differences are small, e.g. some compilers optimize x=x+1
to produce the same bytecode as x++
, others don’t.
Others can have more impact, e.g. the standard did not specify how to generate the names of synthetic members used to implement inner class access to private members (and similar things) in the past (I don’t know whether it does today). But the algorithm for calculating a default serialVersionUID
used a hash code over all class members, even synthetic ones.
As a consequence, compiling with javac
or the first Eclipse versions created classes with incompatible serialVersionUID
s. Today, Eclipse uses the same name schema for synthetic members as javac
and issues a warning about missing explicit serialVersionUID
s in Serializable
classes by default.
There’s still a lot of freedom and even packing with pack200
and unpacking may create classes with different byte code than the original classes.
Upvotes: 2
Reputation: 1768
The comment in question does not actually disagree. Note that you are mixing up two different things here: Java bytecode compilers (javac
) and Java just-in-time compilers (such as HotSpot or J9). You normally use some javac implementation to translate java source code to java bytecode.
Then you take the bytecode and execute it in a JVM, which uses another compiler.
Again, there are two sets of compilers:
.java
to .class
).class
files)(EDIT: Neither of these are guaranteed to produce identical results (i.e., the same java
file can yield different class
files, and the same class
file can yield different machine code when the JIT is done with it.))
The reason for having two sequential compilation processes is that if you wrap everything into one compiler, you lose two properties:
Upvotes: 2