如此问题所讨论的,
我的问题是:给定
java.awt.geom.Area
的equals
方法被定义为:
public boolean equals(Area other)
而不是覆盖来自Object
的equals
方法。该问题涵盖了“为什么”,我对“如何强制Java使用最合适的equals
方法”感兴趣。
考虑以下示例:
public static void main(String[] args) {
Class<?> cls = Area.class;
Area a1 = new Area(new Rectangle2D.Double(1, 2, 3, 4));
Area a2 = new Area(new Rectangle2D.Double(1, 2, 3, 4));
System.out.println("Areas equal: " + a1.equals(a2)); // true
Object o1 = (Object) a1;
Object o2 = (Object) a2;
System.out.println("Objects equal: " + o1.equals(o2)); // false
// Given only cls, o1, and o2, how can I get .equals() to return true?
System.out.println("cls.cast() approach : " + cls.cast(o1).equals(cls.cast(o2))); // false
try {
Method equalsMethod = cls.getMethod("equals", cls); // Exception thrown in most cases
System.out.println("Reflection approach: " + equalsMethod.invoke(o1, o2)); // true (when cls=Area.class)
} catch (Exception e) {
e.printStackTrace();
}
}
我的问题是:给定
o1
,o2
和cls
,其中o1
和o2
保证是cls
(或其子类)的实例,我该如何调用最合适的equals
方法?假设cls
是X.class
,我希望有以下行为:
- 如果
X
定义了X.equals(X)
,那么这是“最合适”的选择。(例如:X
是Area
) - 否则,如果
X
定义了X.equals(Object)
,那么这是第二合适的选择。(例如:X
是Rectangle2D
) - 如果以上都不成立,则将调用
Object.equals(Object)
作为后备。(例如:X
是Path2D
)
原则上,我可以使用反射来检查每个上述方法签名,但那似乎太重-handed手了。是否有更简单的方法?
编辑以使内容更清晰:在运行时,o1
,o2
和cls
都会变化,因此我无法像((Area) o1).equals((Area) o2)
那样进行静态转换,因为cls
可能不是始终为Area.class
。但可以保证cls.isAssignableFrom(o1.getClass())
和cls.isAssignableFrom(o2.getClass())
都为true
。
equals
方法,就像项目符号示例所描述的那样。 - k_ssbmap = singletonMap(A, VAL);
简单调用map.contains(B)
将返回false
是可以接受的,那么请继续使用您现有的基于反射的方法。我觉得我已经说得足够多了,以使您相信通用方法将与equals()
的常见定义一致,并与hashCode
保持一致。而Area.equals(Area)
则不是这样,因此远非“通用”。 - M. Prokhorov