รับรหัสต่อไปนี้:
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 Records ( JEP 359 ) ทำงานได้ไม่ดีนักกับอาร์เรย์วิธีการนั้นต้องสร้างด้วย IDE (อย่างน้อยใน IntelliJ โดยค่าเริ่มต้นจะสร้างวิธีการ "มีประโยชน์" นั่นคือพวกเขาใช้วิธีการคงที่ ในArrays
)
หรือมีวิธีการแก้ปัญหาอื่น ๆ ?
toString()
, equals()
และhashCode()
วิธีการของการบันทึกจะดำเนินการโดยใช้การอ้างอิง invokedynamic . ถ้ามีเพียงคลาสที่คอมไพล์แล้วเท่านั้นที่สามารถเข้าใกล้กับวิธีที่Arrays.deepToString
ใช้ในเมธอดโอเวอร์โหลดส่วนตัวในวันนี้มันอาจจะถูกแก้ไขในกรณีดั้งเดิม
Object
เนื่องจากสิ่งนี้อาจเกิดขึ้นกับคลาสที่ผู้ใช้กำหนด เช่นเท่ากับไม่ถูกต้อง
invokedynamic
ไม่มีอะไรเกี่ยวข้องกับการเลือกซีแมนทิกส์ indy เป็นรายละเอียดการใช้งานจริงที่นี่ คอมไพเลอร์อาจปล่อยสัญญาณ bytecode ให้ทำสิ่งเดียวกัน; นี่เป็นวิธีที่มีประสิทธิภาพและยืดหยุ่นกว่าในการไปที่นั่น มันถูกถกเถียงกันอย่างกว้างขวางในระหว่างการออกแบบของเร็กคอร์ดว่าจะใช้ความหมายที่เท่าเทียมกันมากขึ้น (เช่นความเสมอภาคลึกสำหรับอาร์เรย์) แต่สิ่งนี้กลับกลายเป็นทำให้เกิดปัญหามากขึ้นกว่าที่ควรจะเป็น
List
แทนอาร์เรย์?