配列使うとmutableになるから使うべきではない、というのに加えて。生成される hashCode()
と equals(Object)
, toString()
が配列を考慮しない実装になっているため、JavaのRecordでは配列を使わないほうが良いようです。
検証コード
生成される hashCode()
と equals(Object)
の挙動を検証するコードです。
なぜこうなるのか
ObjectMethods
クラスによって生成されるコードを見ると、 Arrays.hashCode(int[])
ではなくint[].hashCode()
が、Arrays.equals(int[], int[])
ではなく int[].equals(Object)
が使われているようです。これは考慮漏れというわけではなく、ObjectMethods
クラスのjavadocに明記されている仕様です。core-libs-devメーリスに質問を投げて確認しました。
実際の実装はObjectMethods
クラスのコードを読むか、以下の記事を参照ください。
望ましい対策
Recordでは配列の代わりに不変コレクションを利用するのが望ましいと思われます。Java 9からimmutable listを作るfactory methodが導入されています。また不変であることを型として示したいならば、GuavaのImmutableList
を使う手もあります。
Recordクラスがmutableになるリスクを受容した上で配列を使う場合は、hashCode()
と equals(Object)
, toString()
を自動生成に頼るのではなくハードコードすることで、この問題を回避可能です。大抵のIDEにはこれらのコードを自動的に生成する機能が備わっているので、利用すると良いでしょう。