Gegeben den folgenden Code:
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
}
Es scheint offensichtlich, das Arrays toString
, equals
Methoden verwendet werden (anstelle von statischen Methoden Arrays::equals
, Arrays::deepEquals
oder Array::toString
).
Ich denke, Java 14-Datensätze ( JEP 359 ) funktionieren mit Arrays nicht besonders gut. Die jeweiligen Methoden müssen mit einer IDE generiert werden (die zumindest in IntelliJ standardmäßig "nützliche" Methoden generiert, dh sie verwenden die statischen Methoden in Arrays
).
Oder gibt es eine andere Lösung?
toString()
, equals()
und hashCode()
Verfahren eines Datensatzes implementiert eine invokedynamic Referenz. . Wenn nur das kompilierte Klassenäquivalent näher an dem gewesen wäre, was die Methode heute Arrays.deepToString
in ihrer privaten überladenen Methode tut, hätte es möglicherweise für die primitiven Fälle gelöst.
Object
, da dies auch bei benutzerdefinierten Klassen passieren kann. zB falsch gleich
invokedynamic
hat absolut nichts mit der Auswahl der Semantik zu tun. indy ist hier ein reines Implementierungsdetail. Der Compiler hätte Bytecode ausgeben können, um dasselbe zu tun. Dies war nur ein effizienterer und flexiblerer Weg dorthin. Während des Entwurfs von Datensätzen wurde ausführlich diskutiert, ob eine differenziertere Gleichheitssemantik (wie z. B. tiefe Gleichheit für Arrays) verwendet werden soll, aber dies stellte sich als weitaus problematischer heraus, als es angeblich gelöst wurde.
List
anstelle eines Arrays?