无法解释的使用泛型重载方法的行为

huangapple go评论81阅读模式
英文:

Inexplicable behaviour of overloaded method using generics

问题

class My<T> {

    void overloadMethod(String s) {
        System.out.println("string");
    }

    void overloadMethod(Integer i) {
        System.out.println("integer");
    }

    void overloadMethod(T t) {
        System.out.println("t");
    }
}

public class MyClass01 {

    public static void main(String[] args) {
        String o = "abc";
        new My<String>().overloadMethod(o);
    }
}

这导致了以下错误:

/MyClass01.java:20: 错误: 对overloadMethod的引用不明确
        new My<String>().overloadMethod(o);
                        ^
  My中的overloadMethod(String)和My中的overloadMethod(T)都匹配
  其中T是类型变量:
    T extends Object 在My类中声明
1 个错误

我原本期望会输出 "string",假设类型擦除会确保第三个方法是:

    void overloadMethod(Object t) {
        System.out.println("t");
    }

我在这里漏掉了什么?谢谢。

英文:
class My&lt;T&gt; {

    void overloadMethod(String s) {
        System.out.println(&quot;string&quot;);
    }

    void overloadMethod(Integer i) {
        System.out.println(&quot;integer&quot;);
    }

    void overloadMethod(T t) {
        System.out.println(&quot;t&quot;);
    }
}

public class MyClass01 {

    public static void main(String[] args) {
        String o = &quot;abc&quot;;
        new My&lt;String&gt;().overloadMethod(o);
    }
}

This gives the following error:

/MyClass01.java:20: error: reference to overloadMethod is ambiguous
        new My&lt;String&gt;().overloadMethod(o);
                        ^
  both method overloadMethod(String) in My and method overloadMethod(T) in My match
  where T is a type-variable:
    T extends Object declared in class My
1 error

I was expecting "string" output assuming that type erasure would ensure that the third method would be:

    void overloadMethod(Object t) {
        System.out.println(&quot;t&quot;);
    }

What am I missing here?

Thanks.

答案1

得分: 1

通过将通用class MyClass&lt;T&gt;实例化为特定参数化类型new My&lt;String&gt;().overloadMethod(o);,您已经_有效地_声明了两个具有相同签名的方法:overloadMethod(String s)

这就是编译器错误尝试用以下内容告诉您的原因:„error: reference to overloadMethod is ambiguous“。

> „&hellip;我在这里漏掉了什么吗?&hellip;

因为您说:“我期望得到"string"输出”,听起来您错误地认为您对_class My&lt;T&gt;的声明以某种方式赋予了您的通用方法overloadMethod(String s)_具有参数化多态性的能力。实际上并没有。

英文:

By instantiating the generic class MyClass&lt;T&gt; into the specific parameterized type new My&lt;String&gt;().overloadMethod(o);, you've effectively declared two methods with this same signature: overloadMethod(String s).

That's what the compiler error is trying to tell you with: „error: reference to overloadMethod is ambiguous“.

> „&hellip;What am I missing here?&hellip;

Because you say: „I was expecting "string" output“, it sounds like you're mistakenly assuming that your declaration of class My&lt;T&gt; has somehow imbued your non-generic method overloadMethod(String s) with the powers of parametric polymorphism. It hasn't.

答案2

得分: -1

问题出在 void overloadMethod(T t) 这里,这里的 T 是泛型类,在声明时可以是任何类型,当你声明 new My&lt;String&gt;() 时,T = String,如果尝试注释掉 overloadMethod(String s),你会得到 "t" 作为输出。这里的歧义在于在这种情况下 T = String,所以类中有两个可以调用的方法:

void overloadMethod(String s) = void overloadMethod(T t)

而不知道调用哪一个。

英文:

The problem is the void overloadMethod(T t), here T is generic Class, it could be anything, when you declared
new My&lt;String&gt;() then T = String
try to comment in the overloadMethod(String s), you will get "t" as output
The ambiguity comes into play since T = String in this case, so the class has 2 methods to call

void overloadMethod(String s) =   void overloadMethod(T t)

And doesn't know wich one to call

huangapple
  • 本文由 发表于 2020年7月27日 19:05:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63114015.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定