Java 11:javac --release 和 -source 和 -target 命令行参数有什么区别?

Nic*_*ien 3 java javac java-11

有谁知道使用 --release 和旧的 -source 和 -target 命令行参数之间的区别吗?

在 javac 手册页中: -source 提供与指定版本的源兼容性 -target 为特定 VM 版本生成类文件

--release 为特定的 VM 版本编译。支持的目标:6、7、8、9、10、11

--release 可以将 -source 和 -target 绑定到同一版本吗?

Bri*_*etz 7

--release标志不仅设置源版本和目标版本,还会使编译器使用与指定版本对应的 JDK 库的符号表,防止您意外使用编译 JDK 中存在但指定中不存在的 API。版本。该--release标志是后来添加的,并且在大多数情况下,应该替换--source和 的使用--target


Nic*_*ien 5

我在java编译器的Java 19 SDK源代码中找到了答案:

/**
 * Handles the {@code --release} option.
 *
 * @param additionalOptions a predicate to handle additional options implied by the
 * {@code --release} option. The predicate should return true if all the additional
 * options were processed successfully.
 * @return true if successful, false otherwise
 */
public boolean handleReleaseOptions(Predicate<Iterable<String>> additionalOptions) {
    String platformString = options.get(Option.RELEASE);

    checkOptionAllowed(platformString == null,
            option -> reportDiag(Errors.ReleaseBootclasspathConflict(option)),
            Option.BOOT_CLASS_PATH, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND,
            Option.XBOOTCLASSPATH_PREPEND,
            Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS,
            Option.EXTDIRS, Option.DJAVA_EXT_DIRS,
            Option.SOURCE, Option.TARGET,
            Option.SYSTEM, Option.UPGRADE_MODULE_PATH);

    if (platformString != null) {
        PlatformDescription platformDescription =
                PlatformUtils.lookupPlatformDescription(platformString);

        if (platformDescription == null) {
            reportDiag(Errors.UnsupportedReleaseVersion(platformString));
            return false;
        }

        options.put(Option.SOURCE, platformDescription.getSourceVersion());
        options.put(Option.TARGET, platformDescription.getTargetVersion());

        context.put(PlatformDescription.class, platformDescription);

        if (!additionalOptions.test(platformDescription.getAdditionalOptions()))
            return false;

        JavaFileManager platformFM = platformDescription.getFileManager();
        DelegatingJavaFileManager.installReleaseFileManager(context,
                platformFM,
                getFileManager());
    }

    return true;
}
Run Code Online (Sandbox Code Playgroud)

如代码所示,该--release选项会将源和目标设置为相同的值。

事实上,--release如果已经设置了源或目标,则有一项检查禁止使用该参数。

void checkOptionAllowed(boolean allowed, ErrorReporter r, Option... opts) {
    if (!allowed) {
        Stream.of(opts)
              .filter(options :: isSet)
              .forEach(r :: report);
    }
}
Run Code Online (Sandbox Code Playgroud)