java - 将超类对象放入下界通配符列表时出错
问题描述
我知道在列表上使用下限通配符作为方法参数应该让我们放置该下限及其超类型的元素,但请考虑以下代码:
public class WildcardError {
void foo(List<? super Number> i) {
i = new ArrayList<Integer>(); //compile error
i.add(new Integer(2)); // no error
}
}
现在在这里我明白为什么在方法 foo 的第一个语句中存在编译错误,因为 Integer 的 ArrayList 不是“?super Number”的 List 的子类型,但是为什么我们允许将 Integer 放入此列表中,即使 integer 不是Number 的超类型?在以下代码中也是相反的:
public class WildcardError {
void foo(List<? super Integer> i) {
i = new ArrayList<Number>(); //no error
Number k =20;
i.add(k); // compile error
}
}
在这里,我知道语句 2 中应该没有编译错误,因为 Number 的 ArrayList 是“?super Integer”列表的子类型,但为什么最后一条语句出现编译错误?
虽然 ?super Integer 应容纳超类 Number。
我试图找到答案,但无法搜索确切的场景。
解决方案
在第一个示例中,下限? super Number
意味着实际类型参数可以是Number
或者是超类型(例如Object
)。因为 Java 的泛型是不变的,所以 aList<? super Number>
不能匹配ArrayList<Integer>
. 请记住,下限是类型参数的界限,而不是可能作为参数发送的参数类型的界限。调用没有错误,add
因为Integer
可以将 an 传递给add
可能采用 aNumber
或超类的方法。
在第二个示例中,下限? super Integer
意味着实际的类型参数可以是Integer
或者是超类型(例如Number
, Object
)。这匹配ArrayList<Number>
,所以这里没有错误。但是,typei
仍然List<? super Integer>
是 ,不保证可以取Number
比如k
。它可以在任何时候指List<Integer>
一个Number
不Double
应该被接受的地方。这就是这里出现编译器错误的原因。
推荐阅读
- coldfusion - 在 ColdFusion 中注销后如何结束会话
- javascript - 如何读取来自 idp 的 SAML 响应以使用户登录到应用程序
- c++ - PImpl 没有使用 std::unique_ptr 的用户定义构造函数
- c# - Asp Boiler Plate- 角度代理支持
- cassandra-3.0 - 如何使用多节点 cassandra 集群修复 UPDATE 问题
- sql-server - F#类型提供者,2个数据库,一个可以访问元数据一个不能
- python - 面对问题协程'AsyncSocketClient.connect'从未等待龙卷风(套接字)
- javascript - JS进度条颜色不可见
- facetime - swift4 中的 Facetime 群组/电话会议集成
- python - RabbitMQ 不会向控制台打印任何消息