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

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

例如,

boolean equals(Object a, Object b) 

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

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

  boolean equals(T a, T b) 

期望编译时错误,但是我没有错误,因为T会解析为? extends Serializable & Comparable ? extends Serializable & Comparable ,因为DateString实现了SerializableComparable

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

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

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

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

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

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

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

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

编辑

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

  boolean equals(T a, T b) { return true; }  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方法为每个人。