15

考虑以下 2 个方法声明:

1. public abstract <T extends MetaData> List<T> execute();
2. public abstract List<? extends MetaData>  execute();

两者似乎都返回了扩展 MetaData 的对象列表

请问他们有什么区别?

4

3 回答 3

12

在第一种情况下,您将允许 Java 使用类型推断并推断T每个调用站点的类型。

在第二种情况下,您将始终得到 a List<? extends MetaData>,因此无法将其分配给任何更窄类型的变量,例如List<IntegerMetaData>.

于 2012-08-02T13:35:54.617 回答
0

如果有任何子类型,MetaData那么第一个版本只能返回一个空列表或null. 第二个版本可能会返回一个包含实例MetaData及其子类型的列表。

示例:说AB是 的子类型,MetaDataexecute返回一个包含 的实例的列表A。调用者可能像这样调用了execute:

List<B> list = execute(); // the second version does not allow this

调用者说他想要一个Bs 的列表,但得到一个包含 s 的列表A。由于类型擦除,实现execute无法知道调用者要求什么。因此无法实现第一个版本(返回null或空列表除外)。

于 2012-08-02T13:47:10.977 回答
-1

在示例 1 中,您不能必须返回泛型类型为 的 List T,例如:

@Override
public <T extends MetaData> List<T> execute() {
    List<T> l = new ArrayList<T>();
    return l; 
}

在示例 2 中,您可以返回一个泛型类型为 just 的 List MetaData,例如:

@Override
public List<? extends MetaData> execute2() {
    List<MetaData> l = new ArrayList<MetaData>();
    return l;
}

有什么不同?在第一种情况下,该方法具有泛型类型,T必须返回与该类型相关的内容。在第二种情况下,您只返回一个泛型类型,但方法本身没有泛型类型。

于 2012-08-02T13:30:26.383 回答