见下面的简单摘录:
public class GenericsOverloadingDistinguish<T> {
public void print1(T t) {
System.out.println("t");
}
public void print1(Integer i) {
System.out.println("integer");
}
}
public static void main(String[] args) {
new GenericsOverloadingDistinguish<Integer>().print1(new Integer(1));
}
这会导致模糊的方法调用,并且不会编译。
这对该类的用户来说完全令人困惑。它既不能简单地调用print1(T t)
也不能调用print1(Integer i)
,因为它不幸地使用Integer
作为泛型类型。
我理解泛型是编译时并且有类型擦除,但是Java没有什么可以防止这样的错误吗?
如果GenericsOverloadingDistinguish
类被赋予并且无法更改,我只需调用print1(T t)
并T
为整数,该怎么办?
答案 0 :(得分:2)
您可以通过以下方式避免这种情况:
public class GenericsOverloadingDistinguish<T> {
public void print1(T t) {
if (t instanceof Integer)
System.out.println("integer");
else System.out.println("t");
}
}
public static void main(String[] args) {
new GenericsOverloadingDistinguish<Integer>().print1(new Integer(1));
}
如果您的代码是 as-is 并且无法更改,那么您就遇到了问题,因为没有 clean (imo)方法来区分if {应该调用{1}}或T
重载方法。
答案 1 :(得分:2)
如果上课,你运气不好,没有好办法解决问题。
在这种情况下,您如何猜测设计者期望调用哪种方法?你根本无法做到。现在想想编译器如何完成这项工作?
如果类型参数可以被赋予冲突值,那么在该语言中可以完成的是根本不允许这种重载。为什么它没有完成是一个很好的问题,但很难回答。它可能被认为限制太多了。
无论如何,如果你绝对必须,你可以像这样解决这个问题:
GenericsOverloadingDistinguish<Integer> t = new GenericsOverloadingDistinguish<Integer>();
((GenericsOverloadingDistinguish)t).print1((Object)new Integer(1)); //prints "t"
((GenericsOverloadingDistinguish)t).print1(new Integer(1)); //prints "integer"
这是有效的,因为print1(T)
的类型擦除是print1(Object)
。
毋庸置疑,这是一个丑陋的错误,你真的不应该使用原始类型,但这是处理糟糕情况的最不凌乱的方式。