«1. Введение

JDK 11, реализация Java SE 11, выпущенная в сентябре 2018 г.

В этом руководстве мы рассмотрим новую функцию Java 11, позволяющую запускать однофайловые программы с исходным кодом.

2. До Java 11

Однофайловая программа — это программа, помещающаяся в один исходный файл.

До Java 11 даже для однофайловой программы нам приходилось выполнять двухэтапный процесс для запуска программы.

Например, если файл с именем HelloWorld.java содержит класс с именем HelloWorld с методом main(), нам придется сначала его скомпилировать:

$ javac HelloWorld.java

Это сгенерирует файл класса, который нам нужно будет запустите с помощью команды:

$ java HelloWorld
Hello Java 11!

Такие программы являются стандартными на ранних этапах изучения Java или при написании небольших служебных программ. В этом контексте необходимость компилировать программу перед ее запуском несколько церемониальна.

Но было бы здорово использовать одноэтапный процесс? Java 11 пытается решить эту проблему, позволяя нам запускать такие программы непосредственно из исходного кода.

3. Запуск однофайловых программ с исходным кодом

Начиная с Java 11, мы можем использовать следующую команду для выполнения однофайловой программы:

$ java HelloWorld.java
Hello Java 11!

Обратите внимание, как мы передали файл с исходным кодом Java имя, а не класс Java для команды java.

JVM компилирует исходный файл в память, а затем запускает первый найденный публичный метод main().

Мы получим ошибки компиляции, если исходный файл содержит ошибки, но в противном случае он будет работать так же, как если бы мы его уже скомпилировали.

4. Параметры командной строки

Средство запуска Java представило новый режим исходного файла для поддержки этой функции. Режим исходного файла включается, если выполняется одно из следующих двух условий:

  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

Если файл не соответствует стандартным соглашениям об именах для исходных файлов Java, нам нужно использовать параметр –source. Подробнее о таких файлах мы поговорим в следующем разделе.

Любые аргументы, размещенные после имени исходного файла в исходной командной строке, передаются скомпилированному классу при его выполнении.

Например, у нас есть файл Addition.java, содержащий класс Addition. Этот класс содержит метод main(), который вычисляет сумму своих аргументов:

$ java Addition.java 1 2 3

Кроме того, мы можем передавать такие параметры, как – class-path перед именем файла:

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

Теперь мы вы получите сообщение об ошибке, если в пути к классам приложения есть класс с тем же именем, что и класс, который мы выполняем.

Например, предположим, что в какой-то момент разработки мы скомпилировали файл, находящийся в нашем текущем рабочем каталоге, с помощью javac:

$ javac HelloWorld.java

Теперь у нас есть и HelloWorld.java, и HelloWorld.class, присутствующие в текущем рабочем каталоге. :

$ ls
HelloWorld.class  HelloWorld.java

Но если мы попытаемся использовать режим исходного файла, мы получим сообщение об ошибке:

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

5. Файлы Shebang

Это распространено в системах на основе Unix, таких как macOS и Linux, чтобы использовать директиву «#!» для запуска исполняемого файла сценария.

Например, сценарий оболочки обычно начинается с:

#!/bin/sh

Затем мы можем выполнить сценарий:

$ ./some_script

Такие файлы называются «файлами шебанга».

Теперь мы можем выполнять однофайловые программы Java, используя тот же самый механизм.

Если мы добавим в начало файла следующее:

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

Например, добавим следующий код в файл с именем 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);
    }
}

И пометим файл как исполняемый: ~~ ~

$ chmod +x add

Затем мы можем выполнить файл точно так же, как скрипт:

$ ./add 1 2 3
6

Мы также можем явно использовать программу запуска для вызова файла shebang:

$ java --source 11 add 1 2 3
6

Опция –source требуется даже если он уже присутствует в файле. Шебанг в файле игнорируется и рассматривается как обычный файл Java без расширения .java.

Однако мы не можем рассматривать файл .java как файл шебанга, даже если он содержит допустимый шебанг. Таким образом, следующее приведет к ошибке:

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

Последнее, что следует отметить относительно файлов shebang, это то, что директива делает файл зависимым от платформы. Файл нельзя будет использовать на таких платформах, как Windows, которые изначально его не поддерживают.

6. Заключение

«В этой статье мы увидели новую функцию исходного кода с одним файлом, представленную в Java 11.

Как обычно, фрагменты кода можно найти на GitHub.