よりシンプルに、より書きやすく(Project Amber)
今回のJava 25の変更点ではProject Amberが提供するコード記述をよりシンプルにする機能が追加されました。これらはLTSバージョンかつ、正式リリースになっているため、安心してプロジェクトに導入できます。
JEP512:mainメソッドの拡張および簡略化
Java 21で導入された、コンパイルせずにソースコードを直接実行できる機能マルチファイル・ソースコード・プログラムの起動(JEP458)は、Javaをよりスクリプト言語のように扱えるようにしました。
この機能は、プレビュー版として以前に紹介されたJEP477の正式リリースにあたります。
リスト1はこれまでのJavaで必要だった定義をせずにmainメソッドを記述できるようにしたコード例です。
// (1) クラス定義やpublicやstaticなどの指定もいらない
void main(){
IO.println("hello world");
}
従来のJavaでは、mainメソッドを記述するために必ずクラス定義が必要でした。しかし、(1)のようにクラス定義なしで直接mainメソッドを記述できます。
また、これまで通りクラス内でmainメソッドを定義することも可能であり、リスト2のようにインスタンスメソッドとしても定義できるようになりました。
package jp.enbind.java25.jep512;
// import static java.lang.IO.*;
public class Sample {
private final int value;
// (1) コンストラクタ
public Sample(){
this.value = 10;
}
// (2) インスタンスメソッド
void main(){
// (3) Java25からIOクラスは暗黙的には使えない
IO.println("value = " + this.value);
}
}
この場合、通常のインスタンス作成と同じようにコンストラクタが動作し(1)、その後(2)のmainメソッドが実行されます。もちろん、インスタンス変数にもアクセス可能です。
また、Java24(プレビュー機能)までは、IOクラスのメソッドが暗黙的に利用できる状態でしたが、この暗黙的インポートがされなくなりました。従って、IOクラスを明示的に指定するか、サンプルコードのようにimport処理が必要になります。
JEP511:モジュールのインポート宣言
Javaがスクリプト言語のように手軽に書けるようになると、次に気になるのが煩雑なimport文です。
IDE(統合開発環境)の補完機能に頼っている筆者のような開発者にとって、テキストエディタなどでコードを修正する際に、パッケージ名を正確に思い出せないことがあります。このような手間を軽減するため、クラスやパッケージをモジュール単位でまとめてインポートできるようになりました。
package jp.enbind.java25.jep511;
// (1) モジュール単位でインポート
import module java.base;
import module java.sql;
// (2) 重複するクラスの場合の場合のデフォルト指定
import java.util.Date;
public class Sample {
void main(String[] args){
// (3) java.io.Fileをそのまま利用可能
File file = new File(args[0]);
if(!file.exists()){
IO.println("file NOT exists");
}
else{
IO.println("file exists");
}
// (4) 重複するクラスの利用
Date date = new Date();
IO.println("util date is " + date);
}
}
(1)のように「import module <モジュール名>」でモジュール単位でインポート処理が可能です。例えば、java.baseモジュールをインポートすると、java.lang、java.util、java.ioなど、そのモジュールに含まれるすべてのパッケージが自動的にインポートされます。これにより、(3)のようにjava.io.Fileクラスをimport文なしで直接使用できます。
ただし、(4)Dateクラスのように、java.baseモジュール(java.util.Date)とjava.sqlモジュール(java.sql.Date)の両方に同じクラス名が存在する場合があります。その際は、(2)のようにimport文を明示的に記述することで、どちらのクラスを使うのかを明確に指定できます。
[Note]モジュール単位のimportの利用シーンについて
JEP 511は、JEP 512(mainメソッドの簡略化)や JEP 458(ソースコードからの実行)とともに、スクリプト感覚でのコード実行をより快適にする目的で提案された機能です。そのため、プロトタイプや即時実行などの簡易用途では便利ですが、本格的なエンタープライズ用途では不用意な多用は避けた方がよいでしょう。
一方で筆者は、モジュール単位でセキュリティ制御や実行バイナリ構成の管理を行っている場合には積極的な利用もありだと考えます。なぜなら、実運用環境では「どのクラスを使っているか」よりも「どのモジュールの機能を利用しているか」が問題になることが多く、IDEを使えばクラス単位の参照は簡単に追えますが、モジュール依存はコード内に明記されている方が理解しやすいためです。
モジュール依存をコード外(設定ファイルなど)だけで管理していると、後から依存関係を把握するのが難しくなります。しかし、import module ... によってコード内に依存するモジュールが可視化されるようになると、意図が明確化され、メンテナンス性が向上します。
JEP513:より柔軟で自然なコンストラクタ記述の改善
JEP513は、Java22でプレビュー機能として導入され、Java25で正式にリリースされました。この変更点については、Java23のリリースに関する記事でも紹介しており、プレビュー版から大きな変更はありません。したがって、詳細は以前の回を参照してください。
