强制generics方法的两个参数具有相同的具体类型
如何使用具有两个参数的方法,两个参数具有相同的具体类型?
例如,
boolean equals(Object a, Object b)
允许任何类型的任何类型和b
。
我想强迫a
和b
具有相同的具体类型。 我试过了
boolean equals(T a, T b)
期望编译时错误,但是我没有错误,因为T会解析为? extends Serializable & Comparable
? extends Serializable & Comparable
,因为Date
和String
实现了Serializable
和Comparable
。
基本上你不能。 没有办法做到这一点。 即使您可以通过简单的调用来禁止不同类型的参数,也可以使用强制转换来绕过它:
equals((Object) date, (Object) string)
如果您对参数的执行时类型感兴趣,则只能在执行时测试它。 编译器无法知道Date
类型的参数是否具有一个值,该值是对java.util.Date
或某个子类的引用。
事情就是你方法的签名变成了
extends Object> 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
方法为每个人。