重载采用Generic类型的方法会导致模糊的方法调用编译错误

时间:2016-01-30 16:55:29

标签: java generics compilation compiler-errors overloading

见下面的简单摘录:

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为整数,该怎么办?

2 个答案:

答案 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)

毋庸置疑,这是一个丑陋的错误,你真的不应该使用原始类型,但这是处理糟糕情况的最不凌乱的方式。