由于没有人提供令人满意的答案,正确的答案似乎是“无缘无故”。
polygenelubricants 很好地概述了 java 数组协方差发生的坏事,这本身就是一个可怕的特性。考虑以下代码片段:
String[] strings = new String[1];
Object[] objects = strings;
objects[0] = 0;
这个明显错误的代码在编译时没有使用任何“超级”构造,因此不应将数组协方差用作参数。
现在,我有一个完全有效的代码示例,在命名类型参数中需要 super:
class Nullable<A> {
private A value;
// Does not compile!!
public <B super A> B withDefault(B defaultValue) {
return value == null ? defaultValue : value;
}
}
可能支持一些不错的用法:
Nullable<Integer> intOrNull = ...;
Integer i = intOrNull.withDefault(8);
Number n = intOrNull.withDefault(3.5);
Object o = intOrNull.withDefault("What's so bad about a String here?");
如果我完全删除B,后一个代码片段将无法编译,因此确实需要B。
请注意,如果我反转类型参数声明的顺序,从而将super 约束更改为extends,则很容易获得我尝试实现的功能。但是,这只有在我将方法重写为静态方法时才有可能:
// This one actually works and I use it.
public static <B, A extends B> B withDefault(Nullable<A> nullable, B defaultValue) { ... }
关键在于,这种 Java 语言限制确实限制了一些原本可能有用的功能,并且可能需要一些丑陋的变通方法。我想知道如果我们需要 withDefault 是虚拟的会发生什么。
现在,为了与 polygenelubricants 所说的相关联,我们在这里使用 B 不是为了限制作为 defaultValue 传递的对象的类型(参见示例中使用的字符串),而是限制调用者对该对象的期望我们回来。作为一个简单的规则,您可以将extends 用于您需要的类型,将super 用于您提供的类型。