yak shaving life

遠回りこそが最短の道

List.ofで作ったリストでcontainsするとNPEが出る?

タイトルの通り、JavaList.ofで作ったリストでcontains(null)するとぬるぽになった。

jshell> var list = List.of(1, 2);
list ==> [1, 2]

jshell> list.contains(1);
$2 ==> true

jshell> list.contains(3);
$3 ==> false

jshell> list.contains(null);
|  例外java.lang.NullPointerException
|        at Objects.requireNonNull (Objects.java:221)
|        at ImmutableCollections$AbstractImmutableList.indexOf (ImmutableCollections.java:170)
|        at ImmutableCollections$AbstractImmutableList.contains (ImmutableCollections.java:201)
|        at (#4:1)

jshell> list.getClass()
$17 ==> class java.util.ImmutableCollections$List12

別にcontains(null)してもよくない?と思ったので、他のリストでも試してみたら、Arrays.asListで作ったやつは大丈夫だった。new ArrayListでもイケる。

jshell> var list2 = Arrays.asList(1, 2);
list2 ==> [1, 2]

jshell> list2.contains(null);
$7 ==> false

jshell> list2.getClass();
$8 ==> class java.util.Arrays$ArrayList

jshell> list2 instanceof ArrayList;
$9 ==> false

jshell> var arrayList = new ArrayList<>(Arrays.asList(1, 2));
arrayList ==> [1, 2]

jshell> arrayList.contains(null);
$11 ==> false

jshell> arrayList instanceof ArrayList;
$12 ==> true

jshell> arrayList.getClass();
$13 ==> class java.util.ArrayList


jshell> list.add(3)
|  例外java.lang.UnsupportedOperationException
|        at ImmutableCollections.uoe (ImmutableCollections.java:72)
|        at ImmutableCollections$AbstractImmutableCollection.add (ImmutableCollections.java:76)
|        at (#14:1)

jshell> list2.add(3);
|  例外java.lang.UnsupportedOperationException
|        at AbstractList.add (AbstractList.java:153)
|        at AbstractList.add (AbstractList.java:111)
|        at (#15:1)

jshell> arrayList.add(3);
$16 ==> true

要はArrayListArrays$ArrayListはOKだけどImmutableCollections$List12はダメということみたい。ていうかこのクラス何?List12?

確かにデコンパイルされたコードを追っていくとList12containsにはObjects.requireNonNullがあったし、Arrays$ArrayListの方にはなかった。これは意図的なんだろうか…。

みたいな感じで色々考えていたのだが、よく見たら公式ドキュメントに書いてあった。

NullPointerException - if the specified element is null and this list does not permit null elements (optional)

結論:公式ドキュメントを読め。

docs.oracle.com