我正在阅读有关泛型的有效Java第5章,特别是有关偏爱泛型方法的项目。我注意到有时在返回类型之前的方法声明中的类型参数(在尖括号之间)有时被省略。有很多类似的情况,但例如在第二版的第135页上:
public void popAll(Collection<E> dst) {
while (!isEmpty())
dst.add(pop());
}
另一方面,我在声明中看到了类似的通用方法
public <E> void ...
第一个是错字吗?如果不是,我什么时候可以省略声明中的括号?
谢谢
E
是类型变量 -代表其他类型,例如String
或Integer
。因此,就像您不了解dst.add(pop())
不知道在何处和如何dst
定义就无法理解一样,您也无法像popAll(Collection<E> dst)
不了解类型变量在何处以及如何定义那样来理解方法声明E
。对于popAll
,类型变量E
是在类级别定义的Stack<E>
::它是堆栈中元素的类型。您甚至会经常看到它是javadoc'd:
/**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
方法声明的范围内有意义。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句