int value = 0;
for (int i = 0; i < array.length; i++) {
if (array[i].isSelected()) {
value |= (1 << i);
}
}
答案 0 :(得分:3)
它们的行为没有不同,您使用它们的方式也不同。
在此,您要让编译器确定由List
返回的Arrays.asList
的类型,并且在给定List<A>
所需参数的情况下,编译器将其确定为checkWithoutInheritance()
。 :
s.checkWithoutInheritance(Arrays.asList(new B()));
这里您将List<B>
传递给方法,因此编译器别无选择,只能失败:
List<B> list = new ArrayList<>();
s.checkWithoutInheritance(list);
如果您同时使用两个List
,则会得到相同的输出:
均失败:
List<B> list = new ArrayList<>();
List<B> list2 = Arrays.asList(new B());
s.checkWithoutInheritance(list2);
s.checkWithoutInheritance(list);
两个都可以工作
:s.checkWithoutInheritance(Arrays.asList(new B()));
s.checkWithoutInheritance(new ArrayList<>());
对于checkWithInheritance(final Collection<? extends A> s)
,它同时接受List<A>
和List<B>
,这就是为什么您的checkWithInheritance
调用都通过编译的原因。
答案 1 :(得分:1)
有方法时:
void checkWithoutInheritance(final Collection<A> s);
该行:
s.checkWithoutInheritance(Arrays.asList(new B()));
工作正常,因为它与:
相同List<A> list = Arrays.asList(new B());
s.checkWithoutInheritance(list);
但是,以下代码:
List<B> list = new ArrayList<B>();
s.checkWithoutInheritance(list); // compiler error
产生编译器错误,因为无法将泛型are not covariant和List<B>
分配给List<A>
:
List<B> listb = new ArrayList<B>();
List<A> lista = listb; // Incompatible types error, even though B extends A
有方法时:
void checkWithInheritance(final Collection<? extends A> s);
<? extends A>
wildcard放宽了对变量s
的限制,因此两者均有效:
s.checkWithInheritance(new ArrayList<A>());
s.checkWithInheritance(new ArrayList<B>());
<? extends A>
适用于A
和A
子类型的列表。
答案 2 :(得分:0)
List<B> list;
这将声明一个变量,它是一个列表,并保证该列表中的所有内容都可以强制转换为B
(即B
,B
的子类或{ {1}} B`。
null), to which you can only add things which can be cast to
这声明了一个方法,接受一个参数,该参数是一个集合,并保证该集合中的所有内容都可以强制转换为private void checkWithoutInheritance(final Collection<A> s) {
,您只能向其中添加可以强制转换为{{1} }。
这意味着A
可以做到这一点:
A
如果您能够拨打电话
checkWithoutInheritance
然后,s.add(new A());
现在将包含checkWithoutInheritance(list);
的实例,该实例不能转换为list
,从而违反了A
内容的保证。
因此,编译器不允许这样做。编译器不在乎您不要向B
添加list
,因为您可以。出于安全考虑,这是错误的。
另一方面:
A
这声明了一个方法,接受一个参数,该参数是一个集合,并保证该集合中的所有内容都可以转换为 s
的某些子类。
您无法向其中添加private void checkWithInheritance(final Collection<? extends A> s) {
,因为您不知道“某个子类”是指A
,A
还是其他完全含义。
因此,您无法在其方法主体中写入A
,因此将B
传递给它是安全的。