Java泛型WildCard:<?扩展Number> vs

Java泛型WildCard:<?扩展Number> vs <T extends Number>

问题描述:

这两个函数有什么区别?Java泛型WildCard:<?扩展Number> vs <T extends Number>

static void gPrint(List<? extends Number> l) { 
    for (Number n : l) { 
     System.out.println(n); 
    } 
} 

static <T extends Number> void gPrintA(List<T> l) { 
    for (Number n : l) { 
     System.out.println(n); 
    } 
} 

我看到相同的输出。

+3

也许这是因为没有区别? – 2012-07-16 01:07:37

+0

http://*.com/questions/6008241/java-generics-e-and-t-what-is-the-difference – swapy 2012-07-16 07:57:24

+0

为什么我们不能定义类名但类名称是好的? – 2015-07-09 04:45:43

在这种情况下没有区别,因为T从不再使用。

声明T的原因是,您可以再次引用它,从而绑定两个参数类型或返回类型。

+0

同意!那么有没有一种情况只有'?'将为我做这项工作,但不是'T'。或者可以通过通配符完成的任何操作都可以使用'T'完成? – 2012-07-16 01:11:23

+9

如果只有一个'?',那么它是等价的。如果有多个'?',那么您必须使用'T'或'?',这取决于您是否需要这两种类型相同,或者希望允许它们不同。如果你有一个方法'x( a, b)',你可以用Integer和Long来调用它。如果你有'T a,T b',它们都需要是同一类型的。 – Thilo 2012-07-16 01:13:37

+1

但我仍然可以做 x(T a,U b)。那么哪个是首选方式?最好不要使用通配符(只要有可能)? – 2012-07-16 01:24:22

不同之处在于使用通配符时不能引用T

你现在还没有,所以“没有差别”,但这里是你如何可以使用T有所作为:

static <T extends Number> T getElement(List<T> l) { 
    for (T t : l) { 
     if (some condition) 
      return t; 
    } 
    return null; 
} 

这将返回同类型因为无论是通过在如这些都将编译:

Integer x = getElement(integerList); 
Float y = getElement(floatList); 
+0

那么当通配符真的需要时呢? – 2012-07-16 01:25:05

+2

通配符并非真正“需要”,但实际上它是非绑定类型(不需要给它起一个名称),但提供的输入较少。生成的代码是等效的。这与'int a = 1;返回一个'与'返回1'。或者写''T扩展对象>'而不是'' – Thilo 2012-07-16 01:27:39

T是有限制类型,即无论你使用的类型,你必须坚持到延伸Number特定的类型,例如如果将Double类型传递给列表,则不能将它传递给Short类型,因为T的类型为Double,并且该列表已被该类型限制。相反,如果您使用?wildcard),则可以使用扩展为Number的“任意”类型(将ShortDouble都添加到该列表中)。

当您使用T时,您可以在列表上执行所有类型的操作。但是当你使用你不能执行添加。

T - 与完全访问的对象引用相同
? - 给部分访问

static void gPrint(List<? extends Number> l) { 
l.add(1); //Will give error 
for (Number n : l) { 
    System.out.println(n); 
} 

static <T extends Number> void gPrintA(List<T> l) { 
l.add((T)1); //We can add 
for (Number n : l) { 
    System.out.println(n); 
}