如何在运行单文件源代码Java程序时传递编译器选项?

Gun*_*nar 7 java javac java-11

我想使用JEP 330来运行带有Java(> = 11)的单文件源代码程序.

这样做,我想传递编译器(javac)理解的选项,但不传递运行时(java),例如-XDsuppressNotes.这会导致以下调用失败:

java --enable-preview --source=12 -XDsuppressNotes Test.java

Unrecognized option: -XDsuppressNotes
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如何指定此类特定于编译器的选项?

Mik*_*kov 2

\n

在这种情况下,如何指定此类特定于编译器的选项?

\n
\n\n

简短的回答:你不能。

\n\n

这个 JEP 的目标不是取代javac!它只是为了让它更方便,特别是在开始编程的情况下,以达到“运行这个程序”的目标。

\n\n
\n\n

与标准 javac -> java 链相比, JEP-330有一系列限制。来自 JEP 本身的引述:

\n\n
\n

从 JDK 10 开始,java 启动器以三种模式运行:启动类文件、启动 JAR 文件的主类或启动模块的主类。这里我们添加了一种新的第四种模式:启动在源文件中声明的\n 类。

\n\n

...

\n\n

在源文件模式下,效果就好像源文件被编译到内存中,并且执行在源文件中找到的第一个类。例如,如果名为 HelloWorld.java 的文件包含名为 hello.World 的类,则命令

\n\n

java HelloWorld.java

\n\n

非正式地相当于

\n\n

javac -d <memory> HelloWorld.java

\n\n

java -cp <memory> hello.World

\n\n

原始命令行中源文件名后面放置的任何参数在执行时都会传递给已编译的类。例如,如果名为 Factorial.java 的文件包含一个名为 Factorial 的类来计算其参数的阶乘,则命令

\n\n

java Factorial.java 3 4 5

\n\n

非正式地相当于

\n\n

javac -d <memory> Factorial.java

\n\n

java -cp <memory> Factorial 3 4 5

\n\n

在源文件模式下,任何附加命令行选项均按如下方式处理:

\n\n
    \n
  • 启动器扫描源文件之前指定的选项以查找相关的选项,以便编译源文件。这包括:--class-path、--module-path、--add-exports、--add-modules、--limit-modules、--patch-module、--upgrade-module-path 和任何变体这些选项的形式。它还包括新的 --enable-preview 选项,如 JEP 12 中所述。

  • \n
  • 没有规定将任何附加选项传递给编译器,例如 -processor 或 -Werror。

  • \n
\n\n

...

\n
\n\n
\n\n

换句话说,在运行单文件源代码 Java 程序时应牢记某些限制:

\n\n
    \n
  • 没有外部类,仅限单文件程序- 除了正在执行的文件之外,您不得调用文件中的任何其他类。

  • \n
  • 没有可用的类文件- 以这种方式调用该java工具不会生成*.class您可以在工作目录中看到的任何文件。

  • \n
  • 如果类路径中存在现有的类文件,则您\xe2\x80\x99将被迫使用它- 对于文件,例如SampleClass.java,如果存在现有的类文件SampleClass.class,您可能无法调用该java工具来运行源中的源文件 -文件模式。

  • \n
  • 文件名,而不是类名- 该java工具在执行源文件时考虑文件名而不是类名。

  • \n
  • \xe2\x80\x8a文件中的第一个类,不匹配文件类名- 类加载器不再通过匹配文件名和类名来确定要执行的类。文件中的第一个类是将要运行的类,

  • \n
  • 对源文件中的公共文件没有限制- 虽然javac关心源文件中公共类的数量,java但不能\xe2\x80\x99不在乎。

  • \n
  • 您可能无法传递某些编译器特定的参数-您可以传递给 的参数,例如-Werror或,可能不会被该工具传递(或识别)。-nowarnjavacjava

  • \n
\n

  • 很好的答案。但遗憾的是;无法禁用预览注释使得预览功能(这是源文件模式的主要用例)的使用比应有的更加复杂。 (2认同)