Java 为什么在泛型方法的定义中有时会省略返回类型之前的尖括号

Java 为什么在泛型方法的定义中有时会省略返回类型之前的尖括号,java,generics,effective-java,Java,Generics,Effective Java,我正在阅读关于泛型的有效Java第5章,特别是关于偏好泛型方法的内容。我注意到,在返回类型之前的方法声明中,有时会忽略类型参数(尖括号之间)。类似的情况很多,但例如第二版第135页: public void popAll(Collection<E> dst) { while (!isEmpty()) dst.add(pop()); } public void popAll(集合dst){ 而(!isEmpty()) 添加(pop()); } 另一方面,我看到了与声明类似的泛型

我正在阅读关于泛型的有效Java第5章,特别是关于偏好泛型方法的内容。我注意到,在返回类型之前的方法声明中,有时会忽略类型参数(尖括号之间)。类似的情况很多,但例如第二版第135页:

public void popAll(Collection<E> dst) {
while (!isEmpty())
dst.add(pop());
} 
public void popAll(集合dst){
而(!isEmpty())
添加(pop());
} 
另一方面,我看到了与声明类似的泛型方法

public <E> void ...
public-void。。。
第一个是打字错误吗?如果不是,我什么时候可以在声明中省略括号


感谢

不同之处在于,在第一种情况下,整个类被声明为泛型,而在第二种情况下,只有方法是泛型的。

E
是一个类型变量——它代表一些其他类型,如
String
Integer
。因此,正如在不知道
dst
在何处以及如何定义的情况下无法理解
dst.add(pop())
一样,在不知道类型变量
E
在何处以及如何定义的情况下,也无法理解像
popAll(Collection dst)
这样的方法声明。在
popAll
的情况下,类型变量
E
在类级别定义:
Stack
:它是堆栈中元素的类型。您甚至会经常看到它:

/**A Stack of elements
  *
  *@param E The type of elements in the stack */
public class Stack<E>{
    public void popAll(Collection<E> dst){ ... }
}

这里,
E
type变量告诉我们,
list
的元素类型必须与
f
的参数类型和
initVal
的类型相匹配。周围的类并没有为我们定义
E
,它只在
reduce
方法声明的范围内有意义。

答案是。。。不是。“泛型方法”定义为在返回类型之前声明类型变量的方法:

如果方法声明一个或多个类型变量,则该方法是泛型的。()

因此,
popAll
不是一种“通用方法”


由于该方法没有声明类型参数
E
,因此必须在封闭范围内定义它;几乎可以肯定是由包含该方法的类(“泛型类”)创建的。

我不确定为什么会将其标记为重复。所谓的dupe是一个完全不同的问题。因为我不能给出一个合法的答案,我将用一条评论来回答:我相信区别在于,在第一种情况下,整个类被声明为泛型,而在第二种情况下,只有方法是泛型的。投票也重新打开。我无法从另一个问题中找到答案。这些数据似乎是相关的,但不是重复的。
public class ListUtils{
    public static <E> E reduce(List<E> list, Function<E> f, E initVal);
}