Учитывая следующий код:
public static void main(String[] args) {
record Foo(int[] ints){}
var ints = new int[]{1, 2};
var foo = new Foo(ints);
System.out.println(foo); // Foo[ints=[I@6433a2]
System.out.println(new Foo(new int[]{1,2}).equals(new Foo(new int[]{1,2}))); // false
System.out.println(new Foo(ints).equals(new Foo(ints))); //true
System.out.println(foo.equals(foo)); // true
}
Кажется, очевидно, этот массив toString, equalsиспользуются методы (вместо статических методов Arrays::equals, Arrays::deepEquals или Array::toString).
Поэтому я предполагаю, что записи Java 14 ( JEP 359 ) не очень хорошо работают с массивами, соответствующие методы должны генерироваться с помощью IDE (которая, по крайней мере в IntelliJ, по умолчанию генерирует «полезные» методы, то есть они используют статические методы). в Arrays)
Или есть другое решение?
toString(), equals()и hashCode()способы записи реализованы с использованием invokedynamic ссылки. , Если бы только эквивалент скомпилированного класса мог быть ближе к тому, что метод Arrays.deepToStringделает сегодня в своем закрытом перегруженном методе, он мог бы решить проблему для примитивов.
Object, поскольку это может произойти и с пользовательскими классами. например, неверно равно
invokedynamicимеет абсолютно никакого отношения к выбору семантики; Здесь indy - чистая деталь реализации. Компилятор мог выдать байт-код, чтобы сделать то же самое; это был просто более эффективный и гибкий способ добраться туда. Во время разработки записей широко обсуждалось, следует ли использовать более тонкую семантику равенства (например, глубокое равенство для массивов), но оказалось, что это вызывает гораздо больше проблем, чем предполагалось.
Listвместо массива?