0

Consider the following code

class SomeClass {
}

class GenericsExample<E extends SomeClass> {

    public void createError() {
        process(new SomeClass()); //Compiler error!
    }

    public void createWorking() {
        E some = new SomeClass(); //Compiler error!
        process(some);
    }

    public void process(E object) {
    }
}

public class Sandbox {
    public void run() {
        new GenericsExample<SomeClass>().process(new SomeClass()); //Not a compiler error?!
        new GenericsExample().process(new SomeClass()); //Still not a compiler error?!
    }
}

The message for the first error (the second one is essentially the same thing)

required: E
found: SomeClass
reason: actual argument SomeClass cannot be converted to E by method invocation conversion
where E is a type-variable:
  E extends SomeClass declared in class GenericsExample

This can be fixed by casting SomeClass to E, but why should I have to? If a method takes E as an argument and E extends SomeClass, shouldn't it accept SomeClass as an argument? Why is this a compiler error instead of a warning?

And why does this not apply to outside classes, even in cases where I don't even declare the generic type? Why are the rules so different in GenericsExample vs Sandbox?

4

3 回答 3

2
E extends SomeClass

正如你刚刚写E的,与SomeClass.

您不能将基类型的实例分配给更多派生类型的变量,就像您不能编写一样

Button myButton = new Control();  // Not actually a button!

唯一可以分配给 type 变量的是 typeE的实例E

在课堂之外,它只有效,因为您使用的是GenericClass<SomeClass>. 在那里,E SomeClass

于 2013-06-12T18:34:45.803 回答
1

我认为,如果您将其换成更具体的示例,就会变得很清楚。

E假设您将and交换SomeClassIntegerand Number(请原谅扩展而不是实现)来获取Integer extends Number. 在这种情况下,很明显您无法执行以下操作

Integer i = new Number();

因为整数比数字更具体。

于 2013-06-12T18:36:01.513 回答
0

为什么这不适用于外部类,即使我什至没有声明泛型类型?

因为这些是不同的情况:

new GenericsExample<SomeClass>().process(new SomeClass()); 

这不是编译器错误,因为在这里,SomeClass双方都有,而不是 E extends SomeClass.

new GenericsExample().process(new SomeClass()); 

这甚至没有使用泛型,因此您选择退出泛型类型安全(并获得编译器警告)。

于 2013-06-12T18:39:38.833 回答