I understand what source option does, but I don't understand why would someone want to use that.
According to Oracle Docs:
-source: Specifies the version of source code accepted.
Source option restricts the features one can use, for example, -source 1.5 means the compiler accepts features introduced in JDK 5.
I read some article, some point out target and source options are used for backwards compatible. But since backwards compatibility is about jre's version and bytecode's version, shouldn't target option can solely solve this problem?
Then what's the meaning of using source option. Is there any good reason to restrict source code version?
CodePudding user response:
The -source
option is obsolete; whilst there are reasons to set --source
and --target
(all options now have double dashes, too - the single dash variants are also obsolete) separately, these are extremely exotic. Hence, there's the new --release
option which is more or less equivalent to setting both source and target.
There are 3 options relevant for compatibility:
--source
controls what java lang features you are allowed to use. This option doesn't actually work, in the sense that the java lang spec does not cover multiple versions, andjavac
does not actually ship with 10 separate parsers. In effect it more or less causes javac to explicitly mark certain new constructs as invalid, though the parser does know what they mean.--target
controls the class file format version. Eventhough at various times java has gained source features that just compile down to 'ordinary' bytecode (not to some newly introduced bytecode construct without which the language feature cannot be compiled into a class file), source level higher than target level (e.g.-source 17 -target 16
) has never worked - your target option has to be at least as high as the source option. Various transpilers and plugins have existed at various times to bolt this rather useful functionality onto javac.But those 2 together still aren't enough: there's also the core library (essentially, the classes whose package names start with
java.
) - java15 might introduce some new classes which means if you use them, and then compile that withjavac -source 14 -target 14
(or without using these obsolete switches,javac --release 14
), it might well compile fine, but wouldn't actually run on a JDK release 14, due to the class files not being there. You could fix this by setting the bootclasspath of the compiler itself, though this means you need a JDK14 installed for the benefits of having access to a JVM14 version of the core libs to compile against.
Thus, to answer your question: You always set it together with -target
, because -target
on its own does not actually imply 'different source level'. This is kinda silly, and that's why -target
and -source
have been replaced by --release
. Secondly, why would one want to restrict --release
to a lower version? To ensure the class files you end up with also run on a lower version. This can be rather important if, for example, you're releasing a library that other programmers will fetch as dependency and start to use.
CodePudding user response:
It's sometimes necessary for applications to ensure their code is backward compatible with an older version of Java. The target and source options in javac make it easy to accomplish this.