我试图理解,为什么编译器拒绝/接受以下参数。
我假设两个参数都将被接受,因为两个Set都不包含任何东西,而是Serializable的子元素。
并且是Serializable的子对象-是唯一由方法签名D扩展了Serializable的对象-对吗?
为什么类型D的Set serializables1扩展了Serializable可被接受?
为什么Set serializables2类型?扩展Serializable被拒绝?
为什么D扩展了Serializable和?扩展Serializable在这里不一样吗?
public class GenTest<D extends Serializable> {
Set<D> serializables1;
Set<? extends Serializable> serializables2;
public static void main(String[] args) {
GenTest<Serializable> g = null;
g.accept(g.serializables1); // OK - WHY?
g.accept(g.serializables2); // NOT OK - WHY?
}
void accept(Set<D> serializables) {}
}
根据签名,该.accept()
方法使用类作用域的D
类型参数:
void accept(Set<D> serializables) {}
实例GenTest
化为GenTest<Serializable> g = null;
表示D
将在运行时替换为Serializable
。
现在,这Set<? extends Serializable> serializables2
是什么意思?
这意味着serializables2
可以为分配一个Set
的未知子类Serializable
。编译器没有证据表明该未知子类将D
在运行时与替换匹配,因此拒绝编译该代码。
假设您有以下两种类型:
class A implements Serializable { }
class B implements Serializable { }
Set<? extends Serializable> serializables2
表示serializables2
既可以在运行时分配,也可以在运行时Set<A>
分配Set<B>
。假设它被分配了Set<B>
。
现在,如果您g.serializables
仅包含类型的对象A
(这是可能的,因为将D
替换为Serializable
),这意味着在运行时您将获得一个ClassCastException
,当尝试将a传递Set<B>
给方法时,应为其提供一个Set<A>
。
更多信息:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句