为什么
public interface ArrayOfONEITEMInterface <T extends ONEITEMInterface>{
public List<T> getONEITEM();
}
编译,但不是
public interface ArrayOfONEITEMInterface <? extends ONEITEMInterface>{
public List<?> getONEITEM();
}
有什么区别?类和方法签名中的T和T?
答案 0 :(得分:22)
?
是一个通配符,表示 ONEITEMInterface
的任何子类,包括它自己。
T
是ONEITEMInterface
的特定实现。
由于?
是通配符,因此类声明中的?
与方法声明中的?
之间没有关系,因此它不会编译。只是List<?> getONEITEM();
会编译。
第一种情况意味着整个班级可以完全处理一个类型的Bar
每个实例。
interface Foo<T extends Bar> {
List<T> get();
}
第二种情况允许每个实例在{strong> Bar
的任何子类型上运行
interface Foo {
List<? extends Bar> get()
}
答案 1 :(得分:3)
子句<T extends ONEITEMInterface>
声明了一个名为T
的类型参数。这允许您的泛型类型ArrayOfONEITEMInterface
在其他地方引用参数。例如,您可以声明类似void add(T t)
。
如果没有命名类型参数,你会如何引用它?如果您从未参考类型参数,为什么您的类型首先是通用的?例如,您不需要参数化类型来执行以下操作:
public interface ArrayOfONEITEMInterface {
List<? extends ONEITEMInterface> getONEITEM();
}
声明匿名类型参数没有意义,因此它在语法上是非法的。
答案 2 :(得分:2)
T是由实现或实例化类提供的类型的占位符。
?是一个占位符说“我不知道或不关心通用类型是什么”,当您对容器对象的工作不需要知道类型时,通常使用。
你不能使用'?'的原因在类/接口定义中是因为值的意思是定义占位符的名称(类型将在别处提供)。放一个'?'没有意义。
此外,占位符不需要是T,它可以是任何标准的Java变量。按照惯例,它是一个大写字符,但不一定是。
答案 3 :(得分:1)
?允许你有一个未知类型列表,其中T需要一个明确的类型。