为什么这个通配符有效?

时间:2014-04-28 01:13:46

标签: java generics

我对这段代码感到困惑,这段代码应该不起作用(我猜),但似乎没有错误。

当我将<T>放在Person类旁边时,Arraylist中的通配符不会按照定义行事,在下面的代码中,通配符应仅适用于super Person类,但是对于Person类旁边的<T>,它接受​​所有类型的类型(在此示例中它是String)。并且为了使其起作用,人员在定义时不应该具有指定的类型。这是代码:

import java.util.ArrayList;

public class Person {
    public static void main(String[] args) {
        Human h = new Human();
        h.al(new ArrayList<String>()); // this should give an error no ?
    }
}

class Human<T>{ //Human is a generic class, but above I created an instance without specifying the T
    public void al(ArrayList<? super Person> a){ //the type passed should be a super of Person

    }
}

谢谢:)

2 个答案:

答案 0 :(得分:4)

Java Generics FAQ:Can I use a raw type like any other type?

回答了这个问题

答案是:

  

原始类型的方法或构造函数具有在类型擦除后具有的签名。

在英语中,这意味着因为您将h声明为原始类型Human,编译器将在h上执行type erasure以及{{的有效签名1}}方法实际上是类型擦除后的一个!因此,就编译器而言,您的代码是理智的。

另请参阅此问题的答案:Java generics - type erasure - when and what happens 了解更多示例。

维基百科也有一些关于Problems with Type erasures的一些很好的部分可能很难捕捉到。

<强>更新

下面的代码片段将在运行时抛出ClassCastException。

al

答案 1 :(得分:0)

如果使用不带<>的通用参数化类,则对该类变量禁用泛型类型。 如果你这样做:

Human<Object> h = new Human<>();

然后会引发编译器错误。