2013-04-11 75 views
3

为了好玩,我试图在Java中实现一个通用的Pair类。我无法用equals如何为泛型对实现equals?

public class Pair<A, B> 
{ 
    public final A _1; 
    public final B _2; 

    // ... unnecessary details left out ... 

    public boolean equals(Pair<A, B> that) 
    { 
     return (_1.equals(that._1)) && (_2.equals(that._2)); 
    } 

    @Override 
    public boolean equals(Object o) 
    { 
     return (o instanceof Pair<A, B>) && equals((Pair<A, B>) o); 
    } 
} 

然而,o instanceof Pair<A, B>似乎并没有工作。这是为什么?

使用(o instanceof Pair) && equals((Pair<A, B>) o)给我演员一个警告。摆脱演员阵容中的<A, B>部分仍然给我一个警告,我想这也是有道理的。

这是否意味着Java无法阻止客户端将对与不同类型参数进行比较?

+0

难道你不是简单地问如何使用'instanceof'与paremetrized类型? – djechlin 2013-04-11 19:59:21

+0

我认为这应该工作,只要'A'和'B'具有良好行为的'equals()'方法,它应该验证它们的类是否兼容。问题是'A'和'B'类型在运行时被擦除,在这种情况下本质上被简化为'Object'。 – 2013-04-11 19:59:39

回答

6

这是否意味着Java无法阻止客户端将对与不同的类型参数进行比较?

是的,但这就是要点 - equals应该与任何任意对象一起使用。你想要什么看起来像

@Override 
public boolean equals(Object o) 
{ 
    if (o instanceof Pair) { 
     Pair<?, ?> pair = (Pair<?, ?>) o; 
     return _1.equals(pair._1) && _2.equals(pair._2); 
    } 
    return false; 
} 

但是,这应该是罚款,只要AB有需要任意Object S的equals正确实施。

+0

但是,您不会使用从'o'投下的'pair'' – Cratylus 2013-04-11 20:03:12

+0

@Cratylus'pair'和'that '可能是同一个变量的两个名字;) – fredoverflow 2013-04-11 20:33:48

+0

@Cratylus现在修复。 – 2013-04-11 21:17:46

2

由于type erasure的原因,您不能使用instanceof。您只能检查instanceof Pair
还有什么与_1_2?真?

+0

'_1'和'_2'是函数式编程语言中成员对的惯用名称。 – fredoverflow 2013-04-11 20:18:47

+0

@FredOverlow:我怀疑这一点,但在Java中使用是非常规的。 – Cratylus 2013-04-11 20:36:26

+0

在这种情况下:''idiomatic names“.replace(”ma“,”“)';) – fredoverflow 2013-04-11 20:40:21

0
o instanceof Pair<A, B> 

不起作用,因为仿制药是不是有在运行,因此instanceof不知道他们。