它们相同,因为它们接受相同的参数类型。
但是,使用
T(或其他任何一种)标识类型可以让您在其他地方引用该类型。
编辑:示例:
您无限制的示例未充分利用参数化类型的功能。你有:
public static <T> void printList(List<T> list) { for (Object elem : list) System.out.println(elem + " "); System.out.println();}这对于打印字符串表示的示例就足够了,但是请考虑一下(非常人为,并且没有错误处理):
public static <T> T getSecondItem (List<T> list) { T item = list.get(1); return item;}返回类型为T,它使您可以通过编译时类型检查来安全地执行以下操作:
class MyClass { public void myMethod () { }}void somewhere () { List<MyClass> items = ...; getSecondItem(items).myMethod();}命名类型还允许您在多个位置共享相同的类型约束,例如:
public <T> int compareLists (List<T> a, List<T> b) { ...}如果你没有名字的类型,你不能指定约束
a和
b是相同的列表类型(你可以使用
List<? extends T>更多的灵活性)。
您还问“为什么需要
??”。真正的答案是:您不会。我想这主要是为了美学。Java致力于成为一种精确而整洁的语言。在很多情况下,您根本不在乎所指的是哪种类型。在这些情况下,可以使用
?未使用的类型参数声明来避免代码混乱。



