requires a target of 1.5 as well. Naturally, source and target versions that came into existence after a given
compiler was released are not supported.
Each target version causes a change in the class file version number that is encoded in the compiled classes.
Each virtual machine knows what class versions it supports and will generally refuse to load any class files
that have a higher version number. This means, for example, that you can prevent a class from being loaded
on an older virtual machine even if there is no missing functionality in the version.
The default settings for the compiler in the 5.0 release are source 1.5 and target 1.5 to enable all the latest
features of the language. If you compile code to run on previous versions (which doesn't use the new features
of course) you'll need to explicitly set the target to a suitable earlier version.
A.2. Dealing with Multiple Dialects
Adding new keywords to the language runs the risk of breaking existing code, especially if the word is an
identifier as common as "assert" or "enum."[1] The choice to add a new keyword creates some interesting and
important compatibility issues. Taking assertions as an example, you can choose whether or not assert is
recognized in your code by selecting a source version of 1.4 or higher. This allows you to keep your old use of
"assert" in one class, while using the language assertions in anotherprovided the different uses are
independent. When asserts were introduced in the 1.4 release, the default source version was left at 1.3 so by
default nothing changed and you had to explicitly tell the compiler when you were ready to use the new
language feature. In the 5.0 release the presumption is that everyone will want to use at least some of the new
features, so they are enabled by defaultif you don't want them you must either specify the appropriate source
version or use an older version of the compiler.
[1] The keyword strictfp was added to the language in the 1.2 release but caused almost
no problems because nearly nobody had ever used it as an identifier.
These side-by-side dialects can create problems. With only one dialect you could use the same compiler, and
the same compiler options, on all your source code. With two or more dialects you might have some source
files that require assert or enum and others that reject it. You will have to compile your source carefully to
handle such a situation. At this point, there are three dialects: with assert and enum (5.0), with assert
but not enum (1.4), and without either (1.3 and earlier).
The obvious solution is to use a single dialect for all your source. But you will not always have that kind of
control. If you are using source produced by another group they may have moved on while you cannot, or vice
versa.
This is deeper than you might hope. Suppose you have two source files, Newer.java which uses the
assert keyword and Older.java which uses "assert" as a method name. If the newer class depends on
the older and neither has yet been compiled, compiling Newer.java will attempt to compile Older.java
as well. With only one dialect this is a feature. But with the incompatible dialects you will be unable to
compile Newer.java until you have already compiled Older.java under the non-assert dialect. This
complicates your build process because the order in which you compile things has now become significant.
Of course, the ultimate problem is if Newer.java and Older.java depend on each other. Now you have
a loop you cannot solve without modifying one source file. Presumably you would upgrade Older.java to
use the new dialect, but if you cannot do so you will have to regress Newer.java to the older dialect.
Woe betide if you can modify neither.