E
是一个类型变量——它代表一些其他类型,比如String
or Integer
。因此,就像dst.add(pop())
不知道在何处以及如何dst
定义的情况下无法理解一样,您也无法理解方法声明,就像popAll(Collection<E> dst)
不知道类型变量在何处以及如何E
定义的情况下一样。在 的情况下popAll
,类型变量E
是在类级别定义的Stack<E>
::它是堆栈中元素的类型。你甚至会经常看到它是 javadoc 的:
/**A Stack of elements
*
*@param E The type of elements in the stack */
public class Stack<E>{
public void popAll(Collection<E> dst){ ... }
}
另一方面,当您看到类似 的方法声明时public <E> void ...
,类型变量E
正在被声明(不是从封闭类等封闭范围引用)。事实上,大多数时候当你看到一个方法有自己的类型变量时,它是一个静态方法,所以没有封闭的类实例来建立E
.
在这两种情况下,E
类型变量在做什么?它告诉我们两种不同的类型必须如何相互关联。在popAll
中,它告诉我们要放入弹出元素的集合的元素类型必须与要从中弹出它们的堆栈的元素类型相匹配。
同样,以第 136 页的示例为例:
public class ListUtils{
public static <E> E reduce(List<E> list, Function<E> f, E initVal);
}
在这里,E
类型变量告诉我们元素类型list
必须匹配参数类型f
和类型initVal
。周围的类没有E
为我们定义,它只在reduce
方法声明的范围内有意义。