Source, target, class file version decoder ring

Correct usage of javac's -source and -target settings is important to generate class files with the required properties. As Alex has written recently, the compiler's source and target settings interact with various other versioned aspects of the platform. The primary effect of the -source option is to select which version of the Java Programming Language to accept and the primary effect of the -target option is to specify the class file version to output. The first table below summarizes the default source and target settings used by javac in different JDK releases when no explicit -source or -target options are specified. As explained Cross-Compilation Options section of the javc man page, the default target varies depending on the source setting.

In the beginning and through the JDK 1.1 series, javac only had single (implicit) source and single (implicit) target setting. One feature of how inner classes were added in 1.1 was that the class file format did not need to be changed. Therefore, 1.1 and 1.0 share the same target setting. Other subsequent language changes have required later class file versions to be used, sometimes only to force the availability of platform features rather than to intrinsically use new features of the class file format itself. In JDK 1.2, the strictfp modifier was added to the language and to the new class file format selected with target 1.2. The javac in JDK 1.2 always accepts the new keyword, but only generates the new class files supporting the feature if explicitly requested with the -target 1.2 option. Likewise, the JDK 1.3 releases only accept a single implicit source level, unchanged from 1.2, but accept targets ranging from 1.1 to 1.3, with a default of 1.1.

The 1.4 source version added an assert keyword so there was a practical need to be able to compile existing code that happened to use "assert" as an identifier in addition to the new uses of the assert language construct. Therefore, an explicit -source flag was added in JDK 1.4 and retained in subsequent JDK releases. In JDKs 5 and 6, new source and target settings were added. The 1.5 and 1.6 target settings correspond to distinct class file versions; the 1.5 and 1.6 source settings are nearly identical. As an operational difference, javac handles encoding problems differently under those two source levels; an encoding problem generates a warning with source 1.5 but is treated as an error with source 1.6. There is a small semantic difference between the handling of the @Override annotation in the two source levels, but fully elaborating the complications around @Override, source settings, and JDK versions is a story for another day.

The default source and target javac applies in JDK 7 were recently upgraded to source and target 7; previously the same defaults as in JDK 6 were used.

Default javac Source and Target Settings

JDK 1.4.0 and 1.4.1 only accepted source 1.3 and 1.4.

JDK/J2SDK Default Source Source Range Default Target Target Range
1.0.x 1.0 1.1
1.1.x 1.1 1.1
1.2.x 1.2 1.1 1.1 - 1.2
1.3.x 1.2/1.3 1.1 1.1 - 1.3
1.4.x 1.2/1.3 1.2 - 1.4 1.2 1.1 - 1.4
5 1.5 1.2 - 1.5 1.5 1.1 - 1.5
6 1.5 1.2 - 1.6 1.6 1.1 - 1.6
7 1.7 1.2 - 1.7 1.7 1.1 - 1.7

Given the same source code, compilers from different releases configured to use the same source and same target (and same bootclasspath!) can still generate different class files because of bug fixes or changes to compiler-internal contracts. An example of a bug fix, javac -target 1.2 in JDK 1.4.2 elides Miranda methods, extra methods synthesized by the compiler to work around early JVM bugs calling interface methods. Evidence of Miranda methods and other past sins are recorded in javac's class. One compiler-internal contract that has evolved over time is the idiom used to access private members of an enclosing class.

While often updated in small ways, the fundamental structure of class files has been very stable across many releases. The first new bytecode, invokedynamic, is being added in JDK 7; although the pair of jsr/ret bytecodes was effectively removed as of target 1.6. The most common way to add capabilities to the class file format has been the addition of new predefined class file attributes; see table 4.6 in the Java VM Specification, Java SE 7 edition for more information. The table below shows the mapping of javac target settings to class file major.minor version numbers.

Mapping of Targets to Class file major.minor numbers

Target Major.minor Description
1.1 45.3

The original shipped version.

1.2 46.0

Supports the strictfp modifier.

1.3 47.0

Small update.

1.4 48.0

Small update.

5 (1.5) 49.0

New attributes to support generics and other features.
Many more strings accepted as legal identifiers.

6 (1.6) 50.0

StackMaps are supported.

7 (1.7) 51.0

invokedynamic is supported.


Post a Comment:
Comments are closed for this entry.



« March 2015

No bookmarks in folder