JEP 445,Unnamed Classes and Instance Main Methods (Preview),は、Proposed to TargetステータスからTargetedステータスに昇格した。この機能のJEPは、以前はImplicit Classes and Enhanced Main Methods (Preview)というタイトルで、"大規模プログラム用に設計された言語機能を理解する必要がなく、学生が最初のプログラムを書けるようにJava言語を進化させる "という提案をしているのだ。これは、プレビュー言語機能である。
このJDK Enhancement Proposal(JEP)は、初心者にとってJavaをより親しみやすいものにすることを目的としており、オラクル社の著名なエンジニアでJava言語のアーキテクトであるBrian Goetz氏が主導している。 Goetz氏は、OpenJDKのウェブサイトでPaving the on-rampと題して、この提案の背景を詳しく説明しているのだ。Javaは広く教えられている言語で、そのシンプルさが評価されているが、初心者には初期につまずきやすい点があることを認めている。特に、クラスを宣言する必要性や”public static void main”
メソッドの理解は、初心者にとってやや難しい概念であることが多い。
本提案では、このような問題を解決するために、"より寛容な起動プロトコルの導入" "無名クラスの導入" "重要なメソッドやフィールドの事前定義された静的インポートの確立"という3つの大きな変更を行う。これらの変更により、学習プロセスが簡素化され、jshell
やメモ帳、あるいは本格的なIDEでプログラミングを始める人にとって、Javaが歓迎される言語になることが期待される。
この変更により、古典的な"Hello, World!"
プログラムを次のように簡略化できるようになった。
class HelloWorld {
void main() {
System.out.println("Hello, World!");
}
}
2つ目の変更点は、クラス宣言を暗黙のうちに行うことだ。これにより、""Hello, World!
"プログラムはさらに次のように簡略化できる。
void main() {
System.out.println("Hello,World!");
}
3つ目の変更点は、上記のスニペットでは示されていないが、重要なメソッドやフィールドのための事前定義された静的インポートが含まれている。
プレビュー機能として、JDK 21を使用する場合は、JEP 445を明示的に有効にする必要がある。開発者は、--enable-preview
フラグを指定してプログラムをコンパイルすることによって、この機能を利用できるのだ。
javac --release 21 --enable-preview Main.java
そして、--enable-preview
フラグを指定してプログラムを実行する。
java --enable-preview Main
また、ソースコード・ランチャーを使用したい場合は、--enable-preview
フラグを指定してプログラムを実行できる。
開発者は、上記のコマンドの'Main'
を実際のJavaファイルまたはクラスの名前に置き換えることを忘れないでほしい。
Java言語仕様(JLS)は、プログラムのエントリポイントをより柔軟に宣言し、インスタンスのmainメソッドを許可するために、より柔軟な起動プロトコルに更新されている。このプロトコルでは、起動したクラスのmainメソッドにpublic
、protected
、default
のアクセス権を持たせることができ、パラメータを持たない静的mainメソッドのサポートも提供する。静的mainメソッドを持たないクラスでも、非プライベートな0パラメータコンストラクタと非プライベートなインスタンスmainメソッドがあれば、そのクラスのインスタンスを構築し、インスタンスmainメソッドを呼び出し可能である。この柔軟性により、"Hello, World!"
のようなプログラムを、アクセス修飾子、static
修飾子、String[]
パラメータなしで記述できる。また、継承された"レガシー"mainメソッドではなく、インスタンスmainを呼び出すことによる動作の変化があった場合、実行時に警告を発する。
Javaでは、初心者や小規模なプログラムのために言語をさらに単純化するために、無名クラスという概念を導入している。これらの無名クラスは、常に無名パッケージの一部であり、スタンドアロンプログラムまたはプログラムのエントリポイントに役立つのだ。Javaコンパイラは、クラス宣言で囲まれていないメソッドに遭遇すると、そのようなメソッド、囲まれていないフィールド、およびファイル内で宣言されたクラスを、無名トップレベルクラスのメンバーとみなす。無名クラスはfinalであり、インターフェイスの実装やObject以外のクラスの拡張はできず、名前による参照もできない。ただし、Javaコンパイラが強制する要件として、起動可能なmainメソッドを含んでいる必要がある。
この新機能により、開発者は明示的なクラス宣言をせずにプログラムを書くことができる。例えば、"Hello, World!"
は、メソッドとしてだけ、あるいはフィールドを使って書くことができ、トップレベルのメンバーは無名クラスの一部として解釈される。無名クラスがインスタンスmainメソッドを持つ場合、それを起動することは、既存の無名クラス宣言の構造を採用することと同じである。さらに、無名クラスを含むソースファイルをソースコードランチャーで起動し、Javaコンパイラがそのファイルを起動可能なクラスファイルにコンパイルできる。つまり、開発者はプログラムをこう書くこと可能だ。
String greeting() { return "Hello, World!"; }
void main() {
System.out.println(greeting());
}
あるいは、次のようにフィールドを使う。
String greeting = "Hello, World!";
void main() {
System.out.println(greeting);
}
この簡素化により、Javaの柔軟性と使いやすさが向上し、特に、まだコアなプログラミング概念に慣れていない初心者にとって使いやすいものとなる。
開発者がこれらの新機能を試してみたければ、OpenJDK JDK 21 Early-Access BuildsからOpenJDKをダウンロード可能だ。
また、ソフトウェア開発キット・マネージャーであるSDKManを使用して、異なるバージョンのJavaをダウンロードし管理する方法もある。SDKManはコマンドラインから使用でき、その方法を好む開発者にとっては手順を容易にできるのだ。
ただし、これらはearly-access buildsであるため、2023年9月に予定されている最終リリースに比べて安定していない可能性があり、テストとフィードバックを目的としている。