環境
- java (amazon-corretto) 17.0.8
どう違うか?
["a", null]
のソートと [null]
のソートでは NPE 発生有無の振る舞いが違う。
null の element が含まれていれば sort 時に NPE になるんだろなぁ、
と思ったら [null]
のときは起きなくて「ん!?」となった。
["a", null]
のソート
jshell> List<String> s1 = new ArrayList<>();
s1 ==> []
jshell> s1.add("a");
$2 ==> true
jshell> s1.add(null);
$3 ==> true
jshell> s1.sort(String::compareTo);
| 例外java.lang.NullPointerException
| at TimSort.countRunAndMakeAscending (TimSort.java:355)
| at TimSort.sort (TimSort.java:220)
| at Arrays.sort (Arrays.java:1307)
| at ArrayList.sort (ArrayList.java:1721)
| at (#4:1)
[null]
のソート
jshell> List<String> s2 = new ArrayList<>();
s2 ==> []
jshell> s2.add(null);
$6 ==> true
jshell> s2.sort(String::compareTo); // <------- NPE にならない!
jshell> s2
s2 ==> [null]
なんで?
想像付くかもしれませんが、size() <= 1 のときはわざわざソートするまでもないので、
sort() の中では即 return している都合上、element は参照されず NPE にもならない、ということ。
sort() に関連するユニットテスト書いていて NPE にならなかったので、ちょっとハマりました。