?作为类型参数只能在方法中使用。例如:printAll(MyList<? extendsSerializable>)我不能使用?类型参数定义类。
通配符(
?)不是正式的类型参数,而可以用作 类型参数 。在您给出的示例中,方法参数
? extendsSerializable的泛型类型作为类型实参提供。
MyList``printAll
方法还可以声明类型参数,例如类,例如:
static <T extends Serializable> void printAll(MyList<T> myList)
我了解上限
?。printAll(MyList<? extends Serializable>)表示
printAll如果具有实现Serialzable接口的对象,则将打印MyList
更准确地说,这意味着 只有将传递给 具有或实现的某种通用类型的时,
对的调用printAll
才会编译MyList``Serializable
。在这种情况下,它会接受
MyList<Serializable>,
MyList<Integer>等等。
我对有点问题
super。printAll(MyList<? super MyClass>)表示
printAll如果具有MyClass对象或任何扩展MyClass的类 ( MyClass 的后代), 则将打印MyList。
以限制的通配符
super是一个 下限 。因此,我们可以说
,
printAll仅当通过传递
MyList具有
MyClass或的某种超类型的时,才会编译的调用
MyClass。因此,在这种情况下,它将接受
MyList<MyClass>,例如
MyList<MyParentClass>或
MyList<Object>。
因此,假设MyClass看起来像:
public class MyClass extends Thread implements ActionListener{ // whatever}然后,printAll()将在以下情况下打印
- 列表中有MyClass对象
- 列表中有Thread或ActionListener对象
您走在正确的轨道上。但是我认为说“例如,如果
MyClass列表中有对象,它将打印”是有问题的。这听起来像是您在定义运行时行为-
泛型都是关于编译时检查的。例如,即使它可能通过继承包含的实例,也无法将a
MyList<MySubclass>作为参数传递给。我将其改写为:
MyList<? super MyClass>``MyClass
printAll(MyList<? super MyClass>)只有在以下情况下,对的调用才会编译:
MyList<MyClass>
MyList<Thread>
MyList<Runnable>
MyList<ActionListener>
MyList<EventListener>
MyList<Object>
MyList<? super X>
其中X
是MyClass
,Thread
,Runnable
,ActionListener
,EventListener
,或Object
。
因此,在阅读了该问题的许多答案之后,这是我的理解:
? extends T表示 任何扩展T的类 。因此,我们指的是T的子代。因此, T是上限。 继承层次结构中最高级的类? super T表示T的任何类/接口super。因此,我们指的是T的所有父级。 因此T是下限。 继承层次结构中最底层的类
T亲,但我不会说“的孩子”或“其父母
T”,因为这些范围是 包含在内的 -说“
T或其子类型”和“
T或其超类型” 会更准确。



