【问题标题】:Java 11: What is the difference between javac --release and -source and -target command line parameters? [duplicate]Java 11:javac --release 和 -source 和 -target 命令行参数有什么区别? [复制]
【发布时间】:2019-02-23 16:24:18
【问题描述】:

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

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

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

--release 能否将 -source 和 -target 绑定到同一个版本?

【问题讨论】:

标签: java javac java-11


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我在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 选项会将源和目标设置为相同的值。

    事实上,如果 source 或 target 已经设置,有一个检查禁止使用 --release 参数。

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

    【讨论】:

    • 它还将设置 --bootclasspath 标志以链接到正确的运行时,有时仅使用 --source 和 --target 标志就会忘记该运行时。
    【解决方案3】:

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

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

    另外,documentation 的 --release 选项表示:

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

    【讨论】:

      猜你喜欢
      • 2012-05-26
      • 2020-05-25
      • 2016-06-12
      • 2019-08-29
      • 2020-01-15
      • 1970-01-01
      • 2016-11-28
      • 2013-11-25
      • 1970-01-01
      相关资源
      最近更新 更多