Java 11:javac --release和-source和-target命令行参数之间有什么区别? [重复]

问题描述 投票:3回答:3

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

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

-发行针对特定的VM版本进行编译。支持的目标:6、7、8、9、10、11

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

java javac java-11
3个回答
3
投票

我在Java编译器的Java 11 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;
    }

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

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

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

3
投票

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


0
投票

--release选项由"JEP 247: Compile for Older Platform Versions"添加:

javac提供了两个命令行选项,-source-target,可用于分别选择编译器接受的Java语言版本和生成的类文件版本。但是,默认情况下,javac会根据最新版本的平台API进行编译。因此,编译后的程序可能会意外地使用仅在平台的当前版本中可用的API。不管传递给-source-target选项的值如何,此类程序都无法在平台的旧版本上运行。

documentation选项的--release另外说:

注意:使用--release时,也不能同时使用--source / -source--target / -target选项。

© www.soinside.com 2019 - 2024. All rights reserved.