当您想要返回超类型时,这非常方便;就像您在示例中展示的那样。
您以U
为输入并返回T
- 这是U
的超类型; 声明这种关系的另一种方式是T super U
,但在Java中不合法。
这应该是我实际意思的一个例子。假设一个非常简单的类,比如:
static class Holder<T> {
private final T t;
public Holder(T t) {
this.t = t;
}
public <U super T> U whenNull(U whenNull){
return t == null ? whenNull : t;
}
}
该定义的方法whenNull
无法编译,因为在Java中不允许使用U super T
.
相反,您可以添加另一个类型参数并倒置类型:
static class Holder<U, T extends U> {
private final T t;
public Holder(T t) {
this.t = t;
}
public U whenNull(U whenNull) {
return t == null ? whenNull : t;
}
}
使用方法如下:
Holder<Number, Integer> n = new Holder<>(null);
Number num = n.whenNull(22D);
这允许返回一个超类型;但它看起来非常奇怪。我们已经在类声明中添加了另一种类型。
我们可以采用以下方法:
static class Holder<T> {
private final T t;
public Holder(T t) {
this.t = t;
}
public static <U, T extends U> U whenNull(U whenNull, Holder<T> holder) {
return holder.t == null ? whenNull : holder.t;
}
}
甚至可以将这种方法改为静态方法。
对于现有的限制,您可以尝试执行以下操作:
Optional.ofNullable(<SomeSubTypeThatIsNull>)
.orElse(<SomeSuperType>)
T
有意义的方面。你能否提供真实签名的链接/内容? - ThiloAutoBean<Object> autoBean = Foo.<Object, String>getAutoBean("delegate")
。但是仍然不太有意义,因为单一泛型参数的结果是相同的。传递一个Object
并收到一个Object
。 - LinoT
,而是Something<T>
。 - RealSkepticString
扩展了Object
但是Something<String>
不扩展Something<Object>
。 - Lino<T,U extends T> T foo(U u)
中的“特定”并没有什么不同,只需删除U
并将其替换为T
。 Marco13提供的示例与您的示例不完全相同:*它使用的是List <U>
而不是简单的U
*。 我同意,在parameterized type*(Something <U>
)的上下文中,它会有意义,但我怀疑在type parameter*(U
)的上下文中是否也是如此。 - MC Emperor