强制泛型方法的两个参数具有相同的具体类型

时间:2014-09-16 11:08:49

标签: java generics methods

如何使用两个参数的方法,两个参数具有相同的具体类型?

例如,

boolean equals(Object a, Object b)

允许任何类型的a和任何类型的b

我想强制ab具有相同的具体类型。我试过了

<T> boolean equals(T a, T b)

并向该方法输入DateString,期待编译时错误,但我没有错误,因为T将解析为? extends Serializable & Comparable,因为Date String 1}}和Serializable实现Comparable和{{1}}。

3 个答案:

答案 0 :(得分:7)

基本上,你不能。没有办法做到这一点。即使您可以通过简单的调用来禁止不同类型的参数,也可以使用强制转换来绕过它:

equals((Object) date, (Object) string)

如果您对参数的执行时间类型感兴趣,则只能在执行时测试它。编译器无法知道类型Date的参数是否具有对精确 a java.util.Date或某个子类的引用的值。

答案 1 :(得分:1)

事情就是你的方法的签名变成

<? extends Object> boolean equals(? extends Object a, ? extends Object b)

它没有给你任何选择。即使你打电话

equals(new Date(), "hello world");

编译器甚至不需要打破汗水并确定参数类型的最低共同祖先。

修改

有趣的事实。我知道我上面写的是真的,但它仍然看起来有点奇怪。所以我测试了

<T> boolean equals(T a, T b) {
    return true;
}

<T,E> boolean equals(T a, E b) {
    return true;
}

编译器大吼大叫。原因是编译器确实没有区别,只是将两种方法重写为

boolean equals(? extends Object a, ? extends Object b)

在类型擦除后变为

boolean equals(Object a, Object b)

这是完全相同的签名。实际上,如果我保留你的方法equals(T,T)并且我添加另一个带有签名equals(Object, Object)的方法,编译器会继续说我在其他地方声明了相同的方法。

长话短说,由于类型删除,您的方法equals(T,T)equals(Object, Object)相同,因此您无法强制使用相同的参数类型,至少在编译时,除非为每个方法专门实现equals方法。

答案 2 :(得分:0)

正如其他用户所提到的,无法针对特定方法强制执行此操作。但是,如果可能,您可以将此方法移至单独的参数化类,然后在方法签名中使用该参数。

例如:这是我想要强制执行相同参数类型的方法。 (我试图获得 o1 和 o2 之间的差异)

public List<Change> getChanges(Object o1, Object o2);

我将此方法封装在参数化类中。

public class DiffGenerator<T> { 
  public List<Change> getChanges(T o1, T o2) { 
  //code
 }
}

这可以用作: List<Change> changes = new DiffGenerator<MyClass>().getChanges(myClassOld, myClassNew);