Biorąc pod uwagę następujący kod:
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
}
Wydaje się, oczywiście, na tej tablicy toString, equalssposoby są stosowane (zamiast metod statycznych Arrays::equals, Arrays::deepEquals bądź Array::toString).
Sądzę więc, że Java 14 Records ( JEP 359 ) nie działa zbyt dobrze z tablicami, odpowiednie metody muszą zostać wygenerowane za pomocą IDE (które przynajmniej w IntelliJ domyślnie generuje „przydatne” metody, tj. Używają metod statycznych w Arrays).
Czy jest jakieś inne rozwiązanie?
toString(), equals()oraz hashCode()sposoby zapisu są realizowane przy użyciu invokedynamic odniesienia. . Gdyby tylko skompilowany ekwiwalent klasy mógł być bliższy temu, co Arrays.deepToStringrobi dziś metoda w swojej prywatnej, przeciążonej metodzie, mógłby rozwiązać problem pierwotnych przypadków.
Object, ponieważ może się to zdarzyć również w przypadku klas zdefiniowanych przez użytkownika. np. niepoprawny równa się
invokedynamicnie ma absolutnie nic wspólnego z wyborem semantyki; indy jest tutaj czystym szczegółem implementacji. Kompilator mógł wysłać kod bajtowy, aby zrobić to samo; był to po prostu bardziej wydajny i elastyczny sposób dotarcia do celu. Podczas projektowania rekordów szeroko dyskutowano, czy należy stosować bardziej szczegółową semantykę równości (np. Głęboką równość dla tablic), ale okazało się, że powoduje to o wiele więcej problemów, niż przypuszczalnie rozwiązano.
Listzamiast tablicy?