フォーラム » つれづれ Java編 »
返答 (1)
高徹 Javaコードアンチパターン 第4回宿題 - 高橋 徹 さんが約1ヶ月前に追加
List.copyOf() の実装内容はどうなっている?¶
nullが要素に含まれるListに対してcopyOfメソッドを呼ぶとエラーとなるほか、一度copyOfで取得したオブジェクトにcopyOfを呼び出すと再度はコピーしないとなっています。
OpenJDK 25の src.zip を調査対象としました。
- List#copyOf は次のとおり、ImmutableCollections.listCopyに委譲
return ImmutableCollections.listCopy(coll);
- ImmutableCollections#listCopy は次のとおり、少し謎解きが必要なコードです。
if (coll instanceof List12 || (coll instanceof ListN<?> c && !c.allowNulls)) { return (List<E>)coll; } else if (coll.isEmpty()) { // implicit nullcheck of coll return List.of(); } else { return (List<E>)List.of(coll.toArray()); }
List.of(coll.toArray()); を呼んでいます。copyOfで渡したListを配列に変換して呼び出しています。初回のcopyOfで、List12またはListN型のインスタンスが生成されるので(後述)、2回目以降はコピーせず同じインスタンスを返しています。
- List#of(E... elements)
switch (elements.length) { // implicit null check of elements case 0: @SuppressWarnings("unchecked") var list = (List<E>) ImmutableCollections.EMPTY_LIST; return list; case 1: return new ImmutableCollections.List12<>(elements[0]); case 2: return new ImmutableCollections.List12<>(elements[0], elements[1]); default: return ImmutableCollections.listFromArray(elements); }
| 要素数 | 生成するインスタンスの型 |
|---|---|
| 0 | ListN |
| 1 または 2 | List12 |
| 3以上 | ListN |
- List12
要素を1つ、または2つ保持するリストで、要素をObjects.requireNonNullで検査しています。
- ListN
ImmutableCollections#listFromArray()メソッドで ListNを生成します。要素をそれぞれObjects.requireNonNullで検査して詰めています。E[] tmp = (E[])new Object[input.length]; // implicit nullcheck of input for (int i = 0; i < input.length; i++) { tmp[i] = Objects.requireNonNull(input[i]); }
IntelliJ IDEAでnull許容性アノテーションを自動的に推測¶

インターネット非接続で上述の表示ができました(WiFiをオフしてIntelliJ IDEA再起動しての表示)。
無限再帰発生時のStackOverflowErrorのスタックトレースの内容¶
実行すると次のようにStackOverflowErrorのスタックトレースが表示されるので
無限再帰と分かります。
Exception in thread "main" java.lang.StackOverflowError
at ch5.ButtonWrapper.onPressed(ButtonWrapper.java:22)
at ch5.ButtonWrapper.onPressed(ButtonWrapper.java:22)
at ch5.ButtonWrapper.onPressed(ButtonWrapper.java:22)
at ch5.ButtonWrapper.onPressed(ButtonWrapper.java:22)
:
(1000行ほど続く)
Character.isDigit()の仕様は?¶
Character.isDigit のJavadoc API記述では、
getType(codePoint)により示される汎用カテゴリ型がDECIMAL_DIGIT_NUMBERの場合、文字は数字になります。
とあります。DECIMAL_DIGIT_NUMBER の説明では
Unicode仕様の汎用カテゴリ「Nd」。
とあります。
OpenJDK 25(Java SE 25)は、Unicode 16.0.0をサポートしています。
Unicode 16.0.0において、文字の種類(Nd:Decimal Digit Number)について触れている文書
https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-4/
各文字のプロパティは、次のデータ(Unicode Character Database)に記載されています。
https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
ここで、Ndとなっている文字が対象となります。2026-06-20時点のUnicodeData.txtでは770文字が該当します。