Java 11 Single File Source Code – Java 11 单一文件源代码

最后修改: 2018年 12月 14日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

JDK 11, which is the implementation of Java SE 11, released in September 2018.

JDK 11,它是2018年9月发布的Java SE 11的实现。

In this tutorial, we’ll cover the new Java 11 feature of launching single-file source-code programs.

在本教程中,我们将介绍Java 11启动单文件源代码程序的新功能。

2. Before Java 11

2.在Java 11之前

A single-file program is one where the program fits in a single source file.

单文件程序是指程序适合在一个单一的源文件中。

Before Java 11, even for a single-file program, we had to follow a two-step process to run the program.

在Java 11之前,即使是一个单文件的程序,我们也必须遵循两步程序来运行程序。

For example, if a file called HelloWorld.java contains a class called HelloWorld with a main() method, we would have to first compile it:

例如,如果一个名为HelloWorld.java的文件包含一个名为HelloWorld的类,并有一个main()方法,我们必须首先编译它:

$ javac HelloWorld.java

This would generate a class file that we would have to run using the command:

这将产生一个类文件,我们将不得不使用命令来运行:

$ java HelloWorld
Hello Java 11!

Note that since we already created the .class file through compilation, the java command runs it. As proof, we could change the content we print in our original file, but if we don’t compile it another time, running again the same java command will still print ‘Hello world’.

请注意,由于我们已经通过编译创建了.class文件,所以java命令运行它。作为证明,我们可以改变我们在原始文件中打印的内容,但是如果我们不再次编译它,再次运行相同的java命令仍然会打印’Hello world’。

Such programs are standard in the early stages of learning Java or when writing small utility programs. In this context, it’s a bit ceremonial to have to compile the program before running it.

这样的程序在学习Java的早期阶段或编写小型实用程序时是标准的。在这种情况下,在运行程序之前必须先编译程序,这就有点儿仪式感了。

But, wouldn’t it be great to just have a one-step process instead? Java 11 tries to address this, by allowing us to run such programs directly from the source.

但是,如果只需一个步骤,不是很好吗?Java 11试图解决这个问题,它允许我们直接从源代码中运行此类程序。

3. Launching Single-File Source-Code Programs

3.启动单文件源代码程序

First, let’s point out that in Java 11, we can still compile and run our Java programs as we were used to doing with earlier Java versions.

首先,让我们指出,在 Java 11 中,我们仍然可以编译和运行我们的 Java 程序,就像我们习惯于在早期 Java 版本中做的那样。

Additionally, starting in Java 11, we can use the following command to execute a single-file program:

此外,从Java 11开始,我们可以使用以下命令来执行一个单文件程序。

$ java HelloWorld.java
Hello Java 11!

Notice how we passed the Java source code file name and not the Java class to the java command.

注意到我们是如何向java命令传递Java源代码文件名而不是Java类的。

The JVM compiles the source file into memory and then runs the first public main() method it finds.

JVM将源文件编译到内存中,然后运行它发现的第一个公共main()方法。

We’ll get compilation errors if the source file contains errors, but otherwise, it will run just as if we’d already compiled it.

如果源文件包含错误,我们会得到编译错误,但除此之外,它的运行就像我们已经编译过的一样。

Let’s also note that this command is more permissive regarding file name and class name compatibility.

让我们也注意到,这个命令在文件名和类名的兼容性方面是比较宽容的

For instance, if we’d rename our file WrongName.java without changing its content, we can run it:

例如,如果我们重命名我们的文件WrongName.java而不改变其内容,我们可以运行它。

java WrongName.java

This will work, and print the expected result to the console. However, if we try to compile WrongName.java with the ‘javac’ command, we get an error message because the name of the class defined inside the file is not coherent with the name of the file.

这将工作,并将预期的结果打印到控制台。然而,如果我们试图用’javac’命令编译WrongName.java,我们会得到一个错误信息,因为文件内定义的类的名称与文件的名称不一致。

That being said, it is still discouraged to not follow the nearly universal naming conventions. Renaming our file or class accordingly should be the way to go.

尽管如此,我们仍然不鼓励不遵循几乎通用的命名惯例。相应地重命名我们的文件或类,应该是一种方式。

4. Command-Line Options

4.命令行选项

The Java launcher introduced a new source-file mode to support this feature. The source-file mode is enabled if one of the following two conditions are true:

Java启动器引入了新的source-file模式来支持这一功能。如果以下两个条件之一为真,则启用源文件模式。

  1. The first item on the command line followed by the JVM options is a file name with the .java extension
  2. The command line contains the –source version option

If the file does not follow the standard naming conventions for Java source files, we need to use the –source option. We’ll talk more about such files in the next section.

如果该文件不遵循Java源文件的标准命名规则,我们需要使用-source选项。我们将在下一节中详细讨论此类文件。

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, we have a file called Addition.java that contains an Addition class. This class contains a main() method that calculates the sum of its arguments:

例如,我们有一个名为Addition.java的文件,包含一个Addition类。这个类包含一个main()方法,计算其参数的总和。

$ java Addition.java 1 2 3

Also, we can pass options likes  –class-path before the file name:

此外,我们还可以在文件名前传递喜欢的选项-class-path

$ java --class-path=/some-path Addition.java 1 2 3

Now, we’ll get an error if there is a class on the application classpath with the same name as the class we are executing.

现在,如果应用程序classpath上有一个与我们正在执行的类同名的类,我们会得到一个错误

For example, let’s say at some point during development, we compiled the file present in our current working directory using javac:

例如,假设在开发过程中的某个时刻,我们用javac编译了存在于我们当前工作目录中的文件。

$ javac HelloWorld.java

We now have both HelloWorld.java and HelloWorld.class present in the current working directory:

现在我们在当前工作目录中同时有HelloWorld.java和HelloWorld.class存在。

$ ls
HelloWorld.class  HelloWorld.java

But, if we try to use the source-file mode, we’ll get an error:

但是,如果我们试图使用源文件模式,我们会得到一个错误。

$ java HelloWorld.java                                            
error: class found on application class path: HelloWorld

5. Shebang Files

5 Shebang Files

It’s common in Unix-derived systems, like macOS and Linux to use the “#!” directive to run an executable script file.

在Unix衍生的系统中,如macOS和Linux,使用 “#!”指令来运行可执行脚本文件是很常见的。

For example, a shell script typically starts with:

例如,一个shell脚本通常以:

#!/bin/sh

We can then execute the script:

然后我们就可以执行这个脚本了。

$ ./some_script

Such files are called “shebang files”.

这样的文件被称为 “shebang文件”。

We can now execute Java single-file programs using this same mechanism.

我们现在可以用这个机制执行Java单文件程序。

If we add the following to the beginning of a file:

如果我们在一个文件的开头添加以下内容。

#!/path/to/java --source version

For example, let’s add the following code in a file named add:

例如,让我们在一个名为add的文件中添加以下代码。

#!/usr/local/bin/java --source 11

import java.util.Arrays;

public class Addition
{
    public static void main(String[] args) {
        Integer sum = Arrays.stream(args)
          .mapToInt(Integer::parseInt)
          .sum();
        
        System.out.println(sum);
    }
}

And mark the file as executable:

并将该文件标记为可执行文件。

$ chmod +x add

Then, we can execute the file just like a script:

然后,我们可以像脚本一样执行该文件。

$ ./add 1 2 3
6

We can also explicitly use the launcher to invoke the shebang file:

我们也可以明确地使用启动器来调用shebang文件。

$ java --source 11 add 1 2 3
6

The –source option is required even if it’s already present in the file. The shebang in the file is ignored and is treated as a normal java file without the .java extension.

-source选项是必需的,即使它已经存在于文件中。文件中的shebang被忽略,并被视为一个没有.java扩展名的普通java文件。

However, we can’t treat a .java file as a shebang file, even if it contains a valid shebang. Thus the following will result in an error:

然而,我们不能把一个.java文件当作shebang文件,即使它包含一个有效的shebang。因此,下面的内容将导致一个错误。

$ ./Addition.java
./Addition.java:1: error: illegal character: '#'
#!/usr/local/bin/java --source 11
^

One last thing to note about shebang files is that the directive makes the file platform-dependent. The file will not be usable on platforms like Windows, which does not natively support it.

关于shebang文件,需要注意的最后一件事是,该指令使文件依赖于平台。该文件将无法在Windows等平台上使用,因为这些平台不支持该文件。

6. Conclusion

6.结论

In this article, we saw the new single file source code feature introduced in Java 11.

在这篇文章中,我们看到了Java 11中引入的新的单文件源代码功能。

As usual, code snippets can be found over on GitHub.

像往常一样,代码片段可以在GitHub上找到over