Łuk*_*asz 14 java generics bounded-wildcard
简单的课程:
class Pair<K,V> {
}
Run Code Online (Sandbox Code Playgroud)
还有一些任务:
Collection<Pair<String,Long>> c1 = new ArrayList<Pair<String,Long>>();
Collection<Pair<String,Long>> c2 = c1; // ok
Collection<Pair<String,?>> c3 = c1; // this does not compile
Collection<? extends Pair<String,?>> c4 = c1; // ok
Run Code Online (Sandbox Code Playgroud)
为什么第三个子弹不能编译而第四个完全合法?
编译错误:
Type mismatch: cannot convert from Collection<Pair<String,Long>> to Collection<Pair<String,?>>
Run Code Online (Sandbox Code Playgroud)
gex*_*ide 16
我将尝试使用两个简单的规则来解释Java泛型.这些规则足以回答你的问题,基本上足以记住几乎所有情况:
X<A>,X<B>除非是可分配的A = B.即,默认情况下,泛型是不变的.X<A>:
X<?>X<? extends T>iff A可赋值给T(递归地应用规则A和T)X<? super T>iff T可赋值给A(递归地应用规则T和A)c3 = c1在您的示例中,您尝试分配Collection<Pair<String,Long>>给Collection<Pair<String,?>>.也就是说,你的情况A = Pair<String,Long>和B = Pair<String,?>.由于这些类型不相等,它们不可分配; 他们违反了规则1.
问题是,为什么通配符没有帮助?答案很简单:
规则2 不是传递性的.即,X<X<A>>不能被指责X<X<?>>,最外层必须有一个通配符; 否则规则2不适用于最外层.
c4 = c1在这里,你有一个外部类型的通配符.因为它是外部类型,所以规则2开始:A = Pair<String,?>可分配给B = ? extends Pair<String,Long>(再次,因为规则2).因此,这是合法的.
以下是检查任何复杂泛型类型的方法:只需使用这两个规则逐级检查每个泛型级别.从最外层开始.一旦某个级别违反规则,您就知道该分配是非法的; 如果所有级别都遵守规则,那么分配是合法的.让我们再次考虑你的类型:
X = Collection<Pair<String,Long>>
Y = Collection<Pair<String,?>>
Z = Collection<? extends Pair<String,?>>
Run Code Online (Sandbox Code Playgroud)
X可分配给Y吗?
// Outermost level:
A = Pair<String,Long>, B = Pair<String,?>
=> B is no wildcard and A != B (Rule 1), so this is illegal!
Run Code Online (Sandbox Code Playgroud)
X可分配给Z吗?
// Outermost level:
A = Pair<String,Long>, B = ? extends Pair<String,?>
=> We got a wildcard, so Rule 2 states this is legal if the inner level is legal
// Inner level: (we have to check both parameters)
A = String, B = String => Equal, Rule 1 applies, fine!
A = Long, B = ? => B is wildcard, Rule 2 applies, fine!
Run Code Online (Sandbox Code Playgroud)
每个级别的通用嵌套要么必须完全相同(A=B),要么B需要在此级别中包含通配符.
| 归档时间: |
|
| 查看次数: |
557 次 |
| 最近记录: |