【发布时间】:2013-10-03 18:23:35
【问题描述】:
Scheme 知道三种不同的等价运算符:eq?、eqv?、equal?。请参阅here 了解详情。简而言之:eq? 测试引用,eqv? 测试值,equal? 递归测试列表的值。我想编写一个 Java 泛型,它需要 Scheme 的 equal? 的功能。
我尝试使用 Java 的 equals() 方法,因为我认为它会进行值比较,因为对于参考比较,存在 == 运算符,equals 不需要这样做。但是这个假设是完全错误的,因为Java中的equals是完全不可靠的。有时它会进行值比较,有时会进行参考比较。并且无法确定哪个类进行引用比较,哪个类进行值比较。
这意味着equals 不能在泛型中使用,因为泛型不会对所有类型都执行相同的操作。而且也不可能以只接受实现正确值比较的类型的方式限制泛型类型。
所以问题是:如何在泛型中进行可靠的值比较?我必须自己从头开始编写它吗?
顺便说一句:我认为 Java 的同样失败并不是从 Array 开始的。它已经从 Object 开始。我认为两个对象的equals 返回false 是错误的。它必须返回true,因为如果您对没有值的东西进行值比较,则值不能不同,因此它们必须相同。 Scheme 就是这样做的,而且非常合理:(equal? (vector) (vector)) -> #t.
【问题讨论】:
-
您可以使用
SomeClass.getDeclaredMethod("equals", Object.class)来检查一个类是否覆盖了Object.equals(Object)方法。如果一个类确实覆盖了它,那么它很可能会进行某种形式的值比较。但是,仍然不能保证它完全符合您的要求。 -
您也可以使用相同类型的方法(
SomeClass.getDeclaredFields()然后myField.setAccessible(true)和myField.get(myObject)您还必须使用SomeClass.getSuperclass()并对所有超类进行相同的比较' fields) 来查找两个对象的字段并递归检查它们是否具有相同的值,但这听起来有点矫枉过正。 -
欢迎来到 OOP,基本上。
-
@PaulBellora Java,欢迎来到 Java。我们在其他地方有结构等价
-
@PaulBellora Equatable 接口。有些东西确实不应该在结构上进行比较。
标签: java generics scheme equality