如何使用两个参数的方法,两个参数具有相同的具体类型?
例如,
boolean equals(Object a, Object b)
允许任何类型的a
和任何类型的b
。
我想强制a
和b
具有相同的具体类型。我试过了
<T> boolean equals(T a, T b)
并向该方法输入Date
和String
,期待编译时错误,但我没有错误,因为T将解析为? extends Serializable & Comparable
,因为Date
String
1}}和Serializable
实现Comparable
和{{1}}。
答案 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);