When using the same JDK (i.e. the same javac
executable), are the generated class files always identical? Can there be a difference depending on the operating system or hardware? Except of the JDK version, could there be any other factors resulting in differences? Are there any compiler options to avoid differences? Is a difference only possibly in theory or does Oracle's javac
actually produce different class files for the same input and compiler options?
Update 1 I'm interested in the generation, i.e. compiler output, not whether a class file can be run on various platforms.
Update 2 By 'Same JDK', I also mean the same javac
executable.
Update 3 Distinction between theoretical difference and practical difference in Oracle's compilers.
[EDIT, adding paraphrased question]
"What are the circumstances where the same javac executable,when run on a different platform, will produce different bytecode?"
A Java class file is usually produced by a Java compiler from Java programming language source files ( . java files) containing Java classes (alternatively, other JVM languages can also be used to create class files). If a source file has more than one class, each class is compiled into a separate class file.
Answer-> A class file generated when the compiler starts the compilation and exactly at that time a interpreter(JRE) generates class file.
class" files are created in the corresponding folder as there are four classes are defined in the "ClassTest. java" file.
The source code file has file extension ". java". This is the file that is converted into the Java bytecode file, also called the class file. Everything that you physically code is "source code".
Let's put it this way:
I can easily produce an entirely conforming Java compiler that never produces the same .class
file twice, given the same .java
file.
I could do this by tweaking all kinds of bytecode construction or by simply adding superfluous attributes to my method (which is allowed).
Given that the specification does not require the compiler to produce byte-for-byte identical class files, I'd avoid depending such a result.
However, the few times that I've checked, compiling the same source file with the same compiler with the same switches (and the same libraries!) did result in the same .class
files.
Update: I've recently stumbled over this interesting blog post about the implementation of switch
on String
in Java 7. In this blog post, there are some relevant parts, that I'll quote here (emphasis mine):
In order to make the compiler's output predictable and repeatable, the maps and sets used in these data structures are
LinkedHashMap
s andLinkedHashSet
s rather than justHashMaps
andHashSets
. In terms of functional correctness of code generated during a given compile, usingHashMap
andHashSet
would be fine; the iteration order does not matter. However, we find it beneficial to havejavac
's output not vary based on implementation details of system classes .
This pretty clearly illustrates the issue: The compiler is not required to act in a deterministic manner, as long as it matches the spec. The compiler developers, however, realize that it's generally a good idea to try (provided it's not too expensive, probably).
There is no obligation for the compilers to produce the same bytecode on each platform. You should consult the different vendors' javac
utility to have a specific answer.
I will show a practical example for this with file ordering.
Let's say that we have 2 jar files: my1.jar
and My2.jar
. They're put in the lib
directory, side-by-side. The compiler reads them in alphabetical order (since this is lib
), but the order is my1.jar
, My2.jar
when the file system is case insensitive , and My2.jar
, my1.jar
if it is case sensitive.
The my1.jar
has a class A.class
with a method
public class A { public static void a(String s) {} }
The My2.jar
has the same A.class
, but with different method signature (accepts Object
):
public class A { public static void a(Object o) {} }
It is clear that if you have a call
String s = "x"; A.a(s);
it will compile a method call with different signature in different cases. So, depending on your filesystem case sensitiveness, you will get different class as a result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With