Java 11シングルファイルのソースコード

1前書き

これは、2018年9月にリリースされたJava SE 11の実装です。

このチュートリアルでは、単一ファイルのソースコードプログラムを起動するJava 11の新機能について説明します。

2 Java 11より前

単一ファイルプログラムは、プログラムが単一のソースファイルに収まるものです。

Java 11より前は、単一ファイルのプログラムであっても、プログラムを実行するには2段階のプロセスに従う必要がありました。

たとえば、 HelloWorld.java というファイルに main() メソッドを使用して HelloWorld というクラスが含まれている場合は、最初にコンパイルする必要があります。

$ javac HelloWorld.java

これにより、クラスファイルが生成されます。そのクラスファイルは、次のコマンドを使用して実行する必要があります。

$ java HelloWorld
Hello Java 11!

そのようなプログラムは、Javaを学ぶ初期の段階、または小さなユーティリティプログラムを書くときには標準的なものです。この文脈では、実行する前にプログラムをコンパイルする必要があるのはちょっとした儀式です。

  • しかし、その代わりにワンステッププロセスを用意するのは素晴らしいことではないでしょうか?** Java 11では、このようなプログラムをソースから直接実行できるようにすることでこれに対処しています。

3単一ファイルのソースコードプログラムの起動

Java 11以降では、次のコマンドを使用して単一ファイルプログラムを実行できます。

$ java HelloWorld.java
Hello Java 11!

java コマンドにJavaクラスではなくJavaソースコードファイル名を渡したことに注意してください。

  • JVMはソースファイルをメモリにコンパイルしてから、最初に見つかったpublic main() メソッドを実行します。

ソースファイルにエラーが含まれているとコンパイルエラーになりますが、それ以外の場合は、既にコンパイルした場合と同じように実行されます。

** 4コマンドラインオプション

**

Javaランチャーはこの機能をサポートするために新しい ソースファイルモード を導入しました。次の2つの条件のいずれかに該当する場合、ソースファイルモードが有効になります。

  1. コマンドラインの最初の項目の後にJVMオプションが続きます.

拡張子が .java のファイル名 。コマンドラインには – source versionオプションが含まれています。

  • ファイルがJavaソースファイルの標準命名規則に準拠していない場合は、 - source オプションを使用する必要があります。

元のコマンドラインでソースファイルの名前の後に置かれた引数は、実行時にコンパイル済みクラスに渡されます。

たとえば、 Addition クラスを含む Addition.java というファイルがあります。このクラスには、引数の合計を計算する 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ファイル

macOSやLinuxなどのUnix派生システムでは、実行可能なスクリプトファイルを実行するために“#!”ディレクティブを使用するのが一般的です。

たとえば、シェルスクリプトは通常、次の文字列で始まります。

#!/bin/sh

それからスクリプトを実行します。

$ ./some__script

このようなファイルは「shebangファイル」と呼ばれます。

これと同じメカニズムを使用して、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
  • ファイル内のshebangは無視され、 .java 拡張子を持たない通常のJavaファイルとして扱われます。

ただし、有効なshebangが含まれている場合でも、 .java ファイルをshebangファイルとして扱うことはできません。 そのため、次のようにするとエラーになります。

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

shebangファイルについて注意すべき最後のことは、ディレクティブによってファイルがプラットフォームに依存することです。このファイルは、Windowsなどネイティブにはサポートされていないプラットフォームでは使用できません。

6. 結論

この記事では、Java 11で導入された新しい単一ファイルのソースコード機能を見ました。

いつものように、コードスニペットはhttps://github.com/eugenp/tutorials/tree/master/core-java-11[over on GitHub]にあります。