S-JIS[2026-03-20]
Java26のLazy Constants(プレビュー版)について。
2026/3/18にリリースされたJava26で、プレビュー版としてLazyConstantが新設された。
(以前のStableValueがLazyConstantという名前に変更された)
LazyConstantは、遅延初期化する定数を定義できるインターフェース。
(RustのOnceLock相当)
常に使うとは限らない定数で初期化処理が重い場合は、初期化を遅延させたいことがある。
つまり、その定数を持つクラスやインスタンスが生成された時点では初期化を行わず、初めて使うときに一度だけ初期化して、後はその値を使い回す。
そのような場合にLazyConstantは便利。
Javaの定数は、その定数を持つクラスやインスタンスが生成されるときに初期化される。
private static final String CONSTANT = "value"; // 初期化
public static String getConstant() {
return CONSTANT;
}
private static final String CONSTANT;
static {
CONSTANT = "value"; // 初期化
}
public static String getConstant() {
return CONSTANT;
}
が、初めて使うときに初期化したい場合は、finalを外し、ゲッターメソッド内で初期化を行う。
private static String CONSTANT; // 初期値はnull
public static String getConstant() {
if (CONSTANT == null) {
CONSTANT = "value"; // 初期化
}
return CONSTANT;
}
ただ、この方法は、スレッドセーフにしようとすると(マルチスレッドで同時に呼ばれても(効率よく)一度のみ初期化するのは)意外と面倒だったりする。
また、finalが付いていた方がJavaによる最適化の手助けになるらしい。
そこでLazyConstantを使い、以下のように書くことが出来る。
private static final LazyConstant<String> CONSTANT = LazyConstant.of(() -> "value"); // 初期化
public static String getConstant() {
return CONSTANT.get();
}
LazyConstantはJava26ではプレビュー版の機能なので、この機能を使いたい場合はコンパイル時にjavacコマンドに--enable-previewを付ける必要があり、
また、実行時にjavaコマンドに--enable-previewを付ける必要がある。
JShellで試す場合もjshellコマンドに--enable-previewを付ける。
> javac --enable-preview --release 26 Example.java > java --enable-preview Example
> java --enable-preview Example.java
| メソッド | 説明 | 例 |
|---|---|---|
LazyConstant<T> of(Supplier<T> computingFunction) |
値の初期化用のSupplierを指定してLazyConstantオブジェクトを生成する。 | static final LazyConstant<String> OF = LazyConstant.of(()->"value"); |
| メソッド | 説明 | 例 |
|---|---|---|
boolean isInitialized() |
値が初期化されたかどうかを返す。 | boolean b = OF.isInitialized(); |
T get() |
値を取得する。 値が初期化されていない場合は初期化される。 |
String s = OF.get(); |
T orElse(T other) |
値を取得する。 値が初期化されていない場合はotherを返す。(値は初期化されない) |
String s = OF.orElse("else"); |