运行 单文件源代码 Java 程序时如何传递编译器选项?
How to pass compiler options when running a single-file source-code Java program?
我想使用 JEP 330 到 运行 具有 Java (>= 11) 的单文件源代码程序。
这样做,我想传递编译器 (javac) 而不是 运行time (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.
在这种情况下如何指定此类特定于编译器的选项?
How can I specify such compiler-specific option in this case?
简答:你不能。
这个JEP的目标不是要取代javac
!只是为了更方便,尤其是在刚开始编程的情况下达到"run this program".
的目的
JEP-330 与标准 javac -> java 链相比有一系列限制。 JEP 本身的引述:
As of JDK 10, the java launcher operates in three modes: launching a
class file, launching the main class of a JAR file, or launching the
main class of a module. Here we add a new, fourth mode: launching a
class declared in a source file.
...
In source-file mode, the effect is as if the source file is compiled into memory, and the first class found in the source file is executed. For example, if a file called HelloWorld.java contains a class called hello.World, then the command
java HelloWorld.java
is informally equivalent to
javac -d <memory> HelloWorld.java
java -cp <memory> hello.World
Any arguments placed after the name of the source file in the original command line are passed to the compiled class when it is executed. For example, if a file called Factorial.java contains a class called Factorial to calculate the factorials of its arguments, then the command
java Factorial.java 3 4 5
is informally equivalent to
javac -d <memory> Factorial.java
java -cp <memory> Factorial 3 4 5
In source-file mode, any additional command-line options are processed as follows:
The launcher scans the options specified before the source file for any that are relevant in order to compile the source file. This includes: --class-path, --module-path, --add-exports, --add-modules, --limit-modules, --patch-module, --upgrade-module-path, and any variant forms of those options. It also includes the new --enable-preview option, described in JEP 12.
No provision is made to pass any additional options to the compiler, such as -processor or -Werror.
...
换句话说,运行宁单文件源代码 Java 程序时应牢记某些限制:
没有外部 classes,仅限单文件程序 - 你不能在其他文件中调用任何其他 classes比你正在执行的文件。
没有 class 文件可用 - 以这种方式调用 java
工具不会产生任何 *.class
您可以在工作目录中看到的文件。
如果现有 class 文件存在于 class 路径中,您将被迫使用它 - 对于一个文件,比如说SampleClass.java
,如果存在 class 文件,例如 SampleClass.class
,您可能无法调用 java
工具以 运行 源文件模式下的源文件.
文件名,而不是 class 名称 - java
工具考虑文件名而不是文件名class正在执行源文件。
文件中的第一个 class,不匹配文件-class 名称 - class 加载程序不再通过匹配文件名和class名称来确定要执行的class。文件中的第一个 class 将是 运行、
对源文件中的 public 个文件没有限制 - 而 javac
关心 public 的数量class在源文件中,java
不在乎。
您不能传递某些特定于编译器的参数 - 您可以传递给 [=] 的 -Werror
或 -nowarn
等参数10=],可能不会被 java
工具传递(或识别)。
Short answer: you can't.
错了,你可以。
奇怪,--source 11
选项必须出现两次:Before 和 after 所有其他选项:
#!/usr/bin/java --source 11 -ea -cp path/to/jars --source 11
// There appears to be a bug in JDK 11.0.2 single-file mode: The first option must
// be "--source 11" to enable single-file mode, but then the "-cp" DISABLES
// single-file mode (bug). The workaround is to repeat the "--source 11" option
// right after the "-cp" option.
测试
java version "11.0.2" 2019-01-15 LTS
GNU bash, Version 4.4.12(3)-release (x86_64-unknown-cygwin)
我想使用 JEP 330 到 运行 具有 Java (>= 11) 的单文件源代码程序。
这样做,我想传递编译器 (javac) 而不是 运行time (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.
在这种情况下如何指定此类特定于编译器的选项?
How can I specify such compiler-specific option in this case?
简答:你不能。
这个JEP的目标不是要取代javac
!只是为了更方便,尤其是在刚开始编程的情况下达到"run this program".
JEP-330 与标准 javac -> java 链相比有一系列限制。 JEP 本身的引述:
As of JDK 10, the java launcher operates in three modes: launching a class file, launching the main class of a JAR file, or launching the main class of a module. Here we add a new, fourth mode: launching a class declared in a source file.
...
In source-file mode, the effect is as if the source file is compiled into memory, and the first class found in the source file is executed. For example, if a file called HelloWorld.java contains a class called hello.World, then the command
java HelloWorld.java
is informally equivalent to
javac -d <memory> HelloWorld.java
java -cp <memory> hello.World
Any arguments placed after the name of the source file in the original command line are passed to the compiled class when it is executed. For example, if a file called Factorial.java contains a class called Factorial to calculate the factorials of its arguments, then the command
java Factorial.java 3 4 5
is informally equivalent to
javac -d <memory> Factorial.java
java -cp <memory> Factorial 3 4 5
In source-file mode, any additional command-line options are processed as follows:
The launcher scans the options specified before the source file for any that are relevant in order to compile the source file. This includes: --class-path, --module-path, --add-exports, --add-modules, --limit-modules, --patch-module, --upgrade-module-path, and any variant forms of those options. It also includes the new --enable-preview option, described in JEP 12.
No provision is made to pass any additional options to the compiler, such as -processor or -Werror.
...
换句话说,运行宁单文件源代码 Java 程序时应牢记某些限制:
没有外部 classes,仅限单文件程序 - 你不能在其他文件中调用任何其他 classes比你正在执行的文件。
没有 class 文件可用 - 以这种方式调用
java
工具不会产生任何*.class
您可以在工作目录中看到的文件。如果现有 class 文件存在于 class 路径中,您将被迫使用它 - 对于一个文件,比如说
SampleClass.java
,如果存在 class 文件,例如SampleClass.class
,您可能无法调用java
工具以 运行 源文件模式下的源文件.文件名,而不是 class 名称 -
java
工具考虑文件名而不是文件名class正在执行源文件。文件中的第一个 class,不匹配文件-class 名称 - class 加载程序不再通过匹配文件名和class名称来确定要执行的class。文件中的第一个 class 将是 运行、
对源文件中的 public 个文件没有限制 - 而
javac
关心 public 的数量class在源文件中,java
不在乎。您不能传递某些特定于编译器的参数 - 您可以传递给 [=] 的
-Werror
或-nowarn
等参数10=],可能不会被java
工具传递(或识别)。
Short answer: you can't.
错了,你可以。
奇怪,--source 11
选项必须出现两次:Before 和 after 所有其他选项:
#!/usr/bin/java --source 11 -ea -cp path/to/jars --source 11
// There appears to be a bug in JDK 11.0.2 single-file mode: The first option must
// be "--source 11" to enable single-file mode, but then the "-cp" DISABLES
// single-file mode (bug). The workaround is to repeat the "--source 11" option
// right after the "-cp" option.
测试
java version "11.0.2" 2019-01-15 LTS
GNU bash, Version 4.4.12(3)-release (x86_64-unknown-cygwin)