Source, target, class file version decoder ring
By darcy on Aug 05, 2009
Correct usage of
-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
-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 "
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.
† 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.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
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
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.
The original shipped version.
attributes to support generics and other features.
StackMaps are supported.
invokedynamic is supported.