【发布时间】:2020-07-30 08:11:00
【问题描述】:
给定以下代码:
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 中的静态方法)。
或者有其他解决方案吗?
【问题讨论】:
-
用
List代替数组怎么样? -
我不明白为什么必须使用 IDE 生成这些方法?所有方法都应该可以手动生成。
-
记录的
toString(),equals()和hashCode()方法实现using an invokedynamic reference.。如果只有编译后的类等价物可以更接近Arrays.deepToString今天在其私有重载方法中所做的,它可能已经解决了原始情况。 -
第二个实现的设计选择,对于不提供这些方法的覆盖实现的东西,回退到
Object不是一个坏主意,因为这可能发生在用户定义的类中好吧。例如incorrect equals -
@Naman 使用
invokedynamic的选择与语义的选择完全无关; indy 在这里是一个纯粹的实现细节。编译器可以发出字节码来做同样的事情;这只是到达那里的一种更有效和更灵活的方式。在记录设计过程中广泛讨论了是否使用更细微的相等语义(例如数组的深度相等),但结果证明这导致的问题比预期的要多得多。
标签: java arrays java-14 java-record