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

标签 java generics effective-java

我正在阅读《Effective Java》第 5 章有关泛型的内容,特别是有关首选泛型方法的内容。我注意到有时方法声明中返回类型之前的类型参数(尖括号之间)有时会被省略。类似的例子还有很多,比如第二版第135页:

public void popAll(Collection<E> dst) {
while (!isEmpty())
dst.add(pop());
} 

另一方面,我见过类似的带有声明的泛型方法

public <E> void ...

第一个是不是打错了?如果不是,我什么时候可以在声明中省略括号?

谢谢

最佳答案

E是一个类型变量——它代表其他一些类型,例如 StringInteger 。所以就像你无法理解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 type 变量告诉我们 list 的元素类型必须与 f 的参数类型匹配和 initVal 的类型。周围的类没有定义E对于我们来说,只有在reduce范围内才有意义。方法声明。

关于java - 为什么泛型方法的定义中有时会省略返回类型之前的尖括号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60195165/

相关文章:

java - Effective java Item no 74(on serialization) : Implement Serializable judiciously

java - 静态工厂方法不起作用

java - Ho 从另一个 Activity 调用自己的 toast 消息

java - 为什么 Intellij-IDEA 会忽略我的 tomcat/conf/server.xml 上下文标记?

windows - 在 Windows 中找到正在运行的 JRE 目录

c# - 我该如何重构这段代码?

ios - Swift 泛型在使用继承时不会实例化泛型

java - 说 int 枚举模式是编译时常量是什么意思?

java - 我们如何使用 clickAt() 命令而不是 click()?

c# - 空接口(interface) vs 属性,通用约束怎么样?