为什么泛型允许在预期子类型时传递超类型的值?

时间:2013-09-09 13:44:32

标签: java generics

通常,这是一个错误 传递超类型的值,其中包含其子类型的值。

编辑:举一个例子(虽然它非常奇怪)

interface Testing{
    void printValue(TestClient cl);
}

class TestClient implements Testing{

    private String content;
    public TestClient(String content){
        this.content = content;
    }
    @Override
    public void printValue(TestClient cl) {
        // TODO Auto-generated method stub
        System.out.println((cl.content!=null ?cl.content :"Hello World"));
    }

}

public class Test{
    public static void main(String args[]) {
        Testing t = new TestClient("Hi Friends");
        Testing t1 = new TestClient("Hi Enemies");

        t1.printValue(t);  // generates error (The method printValue(TestClient) in the type Testing is not applicable for the arguments (Testing)
    }
}

此处,t1.printValue(t)方法会生成错误The method printValue(TestClient) in the type Testing is not applicable for the arguments (Testing)

  

但在Generics中,每个参数化类型都是一个子类型   对应的原始类型,所以参数化类型的值可以是   在预期原始类型的地方通过。

那么,为什么选择Java 允许在预期参数化类型的地方传递原始类型的值 - 但是,它通过生成未经检查的转换警告来标记这种情况。

2 个答案:

答案 0 :(得分:3)

允许向后兼容为Java 1.4编写的代码/库,或者在可用的泛型之前。 有关详细信息,请参阅What is the concept of erasure in generics in Java?和(可能)http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.8

答案 1 :(得分:0)

这是为了向后兼容。考虑一下这样调用的遗留方法printList(List l)

List l = ...

printList(l);

现在您将方法更改为printList(List<?> l)。如果您不允许调用接受原始类型(在这种情况下禁用类型检查),您将中断调用代码。

这是Java开发人员必须面对的一种情况,因此允许传递原始类型。

另一个原因是由于类型擦除,该方法的原始类型版本仍将在运行时出现。