泛型构造函数的用例是什么?

Pau*_*ora 8 java generics constructor

考虑以下类的构造函数Foo(为了清楚起见,它不是泛型类):

public <T> Foo(T obj) { }
Run Code Online (Sandbox Code Playgroud)

这是构造函数的有效语法,就像使用普通的泛型方法一样.

但是这种语法的用途是什么?通常,泛型方法为其返回类型提供类型安全性,并且可以受益于编译器的类型推断.例如:

Pair<String, Integer> stringInt = Pair.of("asfd", 1234);
Run Code Online (Sandbox Code Playgroud)

但是对构造函数的调用总是返回其声明类的实例,因此其类型参数对返回类型没有影响.上面的构造函数可以用它的擦除替换:

public Foo(Object obj) { }
Run Code Online (Sandbox Code Playgroud)

当然,泛型不仅仅是关于返回类型的类型安全性.构造函数可能只想约束传入的参数类型.但是,上述推理仍适用于有界类型参数:

public <N extends Number> Foo(N number) { }

public Foo(Number number) { } //same thing
Run Code Online (Sandbox Code Playgroud)

甚至带边界的嵌套类型参数也使用通配符处理:

public <N extends Number, L extends List<N>> Foo(L numList) { }

public Foo(List<? extends Number> numList) { } //same thing
Run Code Online (Sandbox Code Playgroud)

那么拥有通用构造函数的合法用例是什么?

Lou*_*man 6

这是一个可能的功能编程改编版.假设我们有一个Stream具有某种内部状态的类型,在它返回之前反复产生新元素null.外部调用者不关心流类型的内部状态类型是什么,所以你可能会得到类似的东西

class Stream<E> {
  <S> Stream(S initialState, StepFunction<E, S> stepFun) {
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

没有收件人必须知道内部状态类型是什么.


Ste*_*ker 5

我可以想到的一件事是,您可以确保跨多个参数以相同的方式实现边界.

采取一个明显愚蠢且设计但有效的构造函数,将列表从源复制到目标:

public <T> Foo (List<T> listA, List<T> listB) {
    listA.addAll(listB);
}
Run Code Online (Sandbox Code Playgroud)

在这里使用通配符会很快变得非常讨厌,可能无论如何也不会做你想要的.不允许它也是完全武断的限制.因此,语言规范允许它对我有意义.

  • 或者在体内使用`T`:`<T> Foo(List <T> ts){T t0 = ts.get(0); ts.set(0,ts.get(1)); ts.set(1,t0); }`.好的,不是一个令人信服的例子. (2认同)