Учитывая следующий код:
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
вместо массива?