这是一个很好的解释的链接<? 超级 T> 和 <? 在 Java 中扩展 T>
书上是正确的“?super String”意味着列表可能包含Strings或String的超类型(例如Object,CharSequence)
在你的例子中:
List<? super String> superString = new ArrayList<>();
superString.add(new String());// 1
superString.add(new Object()); // 2
写操作:
1 - 适用于您可以创建的任何类型的列表,因为 String 是一个对象,一个 CharSequence...
List<? super String> list = new ArrayList<Object>();
list.add("String");
2 - 无效,因为它不涵盖所有情况
List<? super String> list = new ArrayList<String>();
list.add(new Object());
给定声明的类型List<? super String>
,您只能添加字符串(和字符串子类型),任何小于字符串(超类型)的内容可能与实际元素类型不对应。
例子:
这是一个例子:
interface MyInterface {
}
class MyInterfaceImpl implements MyInterface {
}
class MyInterfaceImplExtra extends MyInterfaceImpl {
}
你可能有以下几种情况:
List<? super MyInterfaceImpl> myList = new ArrayList<MyInterfaceImpl>();
无法编译,因为 myList 变量可能指向 MyInterfaceImpl 或 MyInterface 或 Object 的列表。添加到列表时,不清楚您实际拥有什么样的列表,因此只允许您使用适用于所有情况的值。
myList.add(new MyInterface(){}); // - compile error "not applicable for the arguments"
myList.add(new MyInterfaceImpl()); // - works fine
myList.add(new MyInterfaceImplExtra()); // - works fine
获取值列表的示例。元素类型是 Object ,不能保证更具体的类型。例如在这里你期望字符串但得到一个List<? super String>
实际上包含对象的,所以你得到一个java.lang.ClassCastException
List<String> result = (List<String>) getList();
System.out.println(result.get(0));
public static List<? super String> getList(){
List<Object> list = new ArrayList<Object>();
list.add(new Object());
return list;
}
Java 8 中的用法示例:
您在 Stream 接口中有以下方法声明,它将谓词类型限制为 T 或超类型。
Stream<T> filter(Predicate<? super T> predicate);
这确保了给定一个类 Person 定义 name 和 Employee 扩展 Person 并定义一个额外的字段 id ,你不能做这样的事情:
List<Person> list = new ArrayList<Person>() {{
add(new Person("John"));
add(new Person("Max"));
add(new Person("Megan"));
}};
list.stream().filter((Employee e) -> e.getId().startsWith("1")); // compile error