1

我不明白这两个代码片段之间的区别。

T extends List第一个例子中的作用是什么?我可以将其解释为“一种名为see您可以传递toList的类型或子类型的List方法”吗?如果是,为什么不只使用方法2?

1.

public <T extends List> void see(T n) {}

2.

public void see(List n) {}
4

2 回答 2

3

在这个例子中,我认为它没有用。

但在这个:

public <T extends MyClass> T[] toArray(List<T> n) {
   ...
}

它为您提供了一些类型检查(我T在返回类型中重用了)。

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
//I gave a List<Integer> so it returns a Integer[]. No need to cast ! 
Integer[] myArray = toArray(list);

而在这种情况下:

//I don't know the generic type of the list so I return a Object[]
public Object[] toArray(List n) {
   ...
}

您将需要转换结果。

注意:要回答您的问题,此处<T extends MyClass>仅将 的类型限制T为 的子类MyClass

于 2013-09-12T13:11:15.840 回答
1

通常使用“有界泛型类型”,以允许类中方法/或方法的参数类型或返回类型相互关联。

考虑到你的例子1):

public <T extends List> void see(T n) {}

泛型类型必然是 List 的子类型,因此在 JVM 级别,已编译(原始)代码和签名将等同于示例 2)。

但是,编译器如何处理“通用”和“原始”类型存在一些细微的语义差异。“原始”和“泛型”类型之间的转换通常是一个警告,未经检查的泛型类型操作也是如此。

对于正确使用泛型的代码,声明 List (我理解)会更好。由于方法参数之间没有相互关系,因此第二种样式会更简单。

我的建议:

public void see (List<?> items) {}

1) 中的样式对于相互关联的参数/或结果类型更有意义。几个单独的例子,展示了更典型的用法:

public <T>  List<T> getChildren (T parent);
public <T>  List<T> listItems (T list1, T item2);
public <T extends List<?>>  T combineLists (T list1, T list2);

将 T 声明为 item 参数并在其上泛化集合可能比将 T 声明为“集合类型”更常见。

于 2013-09-12T13:06:38.987 回答