我正在尝试一些关于泛型上/下界的示例程序。泛型上界正在给出编译错误......但下限很好。 我只是试图将类型T的List放入一个集合中并尝试上限和下限场景..
请帮助确定testUpperBound(T t)方法的问题,以及为什么testLowerBound(T t)方法正好编译而testUpperBound(T t)方法没有。我检查了其他类似的线程..但我仍然没有说清楚。
如果需要更多详细信息,请告诉我。
public class TestGenerics<T>
{
public static void main(String...args)
{
List<String> list = new ArrayList<>();
list.add("New ArrayList");
new TestGenerics<List<String>>().testUpperBound(list);
new TestGenerics<List<String>>().testLowerBound(list);
}
public void testLowerBound(T t)
{
Set<? super ArrayList<T>> lowerBoundSet = new HashSet<>();
lowerBoundSet = new HashSet<List<T>>();
ArrayList<T> list = new ArrayList<>();
list.add(t);
lowerBoundSet.add(list); // compiles..
out.println(lowerBoundSet);
}
public void testUpperBound(T t)
{
Set<? extends List<T>> upperBoundSet = new HashSet<>();
upperBoundSet = new HashSet<List<T>>();
ArrayList<T> list = new ArrayList<>();
list.add(t);
upperBoundSet.add(list); // Doesn't compile..
out.println(upperBoundSet);
}
}
答案 0 :(得分:0)
您无法修改使用<? extends SomeType>
参数化的集合。 Java只是不允许这样做,因为它不是安全的行动。 add()修改集合,因此您无法执行此操作。 <? super SomeType>
答案 1 :(得分:0)
这里有答案:
Explanation of the get-put principle
这是java规则,就是这样。 我可能会给你一个代码示例,为什么在编译通过时它会不安全:
setOfArrayList
想象一下编译不会失败。
这意味着ArrayList
实例是一个应包含LinkedList
个实例的集合,现在包含setOfArrayList
元素的列表。
如果您对ArrayList<String>
进行迭代,则不会按预期排除<? super
个元素。这不安全,这就是编译失败的原因。
这里的示例包含public void superExample(){
Set<? super ArrayList<String>> setOfArrayList = new HashSet<>();
// compilation ok
setOfArrayList.add(new ArrayList<String>());
// new anonymous type derivating from ArrayList
ArrayList<String> derivedArrayList = new ArrayList<String>(){
};
// compilation ok
setOfArrayList.add(derivedArrayList);
}
:
algoliasearch.angular.js
答案 2 :(得分:0)
简单地说,我们在编译时不知道upperBoundSet
中包含哪种类型的列表。它可以是Set<ArrayList<T>>
,也可以是Set<LinkedList<T>>
,也可以是许多其他选择之一。
如果结果是Set<LinkedList<T>>
,那么添加ArrayList
显然是一个坏主意。但是因为我们不知道该集合的内容是什么类型,所以它需要更安全的选项并阻止它。