Is the creation of Java class files deterministic? Is the creation of Java class files deterministic? java java

Is the creation of Java class files deterministic?


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 LinkedHashMaps and LinkedHashSets rather than just HashMaps and HashSets. In terms of functional correctness of code generated during a given compile, using HashMap and HashSet would be fine; the iteration order does not matter. However, we find it beneficial to have javac'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.


Short Answer - NO


Long Answer

They bytecode need not be the same for different platform. It's the JRE (Java Runtime Environment) which know how exactly to execute the bytecode.

If you go through the Java VM specification you'll come to know that this needs not to be true that the bytecode is same for different platforms.

Going through the class file format, it shows the structure of a class file as

ClassFile {    u4 magic;    u2 minor_version;    u2 major_version;    u2 constant_pool_count;    cp_info constant_pool[constant_pool_count-1];    u2 access_flags;    u2 this_class;    u2 super_class;    u2 interfaces_count;    u2 interfaces[interfaces_count];    u2 fields_count;    field_info fields[fields_count];    u2 methods_count;    method_info methods[methods_count];    u2 attributes_count;    attribute_info attributes[attributes_count];}

Checking about the minor and major version

minor_version, major_version

The values of the minor_version andmajor_version items are the minor and major version numbers of thisclass file.Together, a major and a minor version number determine theversion of the class file format. If a class file has major versionnumber M and minor version number m, we denote the version of itsclass file format as M.m. Thus, class file format versions may beordered lexicographically, for example, 1.5 < 2.0 < 2.1. A Javavirtual machine implementation can support a class file format ofversion v if and only if v lies in some contiguous range Mi.0 vMj.m. Only Sun can specify what range of versions a Java virtualmachine implementation conforming to a certain release level of theJava platform may support.1

Reading more through the footnotes

1 The Java virtual machine implementation of Sun's JDK release 1.0.2supports class file format versions 45.0 through 45.3 inclusive. Sun'sJDK releases 1.1.X can support class file formats of versions in therange 45.0 through 45.65535 inclusive. Implementations of version 1.2of the Java 2 platform can support class file formats of versions inthe range 45.0 through 46.0 inclusive.

So, investigating all this shows that the class files generated on different platforms need not be identical.