[译] 3.泛型和子类型

<< 定义简单泛型 · 目录 · 通配符 >>

                                                                                  

泛型和子类型 (Generics and Subtyping) 

让我们来测试一下你对泛型的理解。下面的代码段合法吗?

List<String> ls = new ArrayList<String>(); // 1
List<Object> lo = ls; // 2

第1行当然是合法的。比较棘手的是第2行。这归结于一个问题:String List 是 Object List 吗?大多数人凭直觉回答:是!

再看看接下来的几行:

lo.add(new Object()); // 3
String s = ls.get(0); // 4: 尝试将Object分配给String!

这里我们别名化了 ls 和 lo 。通过别名 lo 访问 ls (一个 String List),我们可以向其中插入任意对象。因此 ls 不再只保存String,当我们试图从中得到一些东西时,我们会得到一个“惊喜”。

当然,Java编译器将防止这种情况发生。第2行将导致编译时错误。

通常,如果Foo是Bar的子类型(子类或子接口),而G是泛型类型声明,但 G<Foo> 却不是 G<Bar> 的子类型。这可能是你需要学习的关于泛型的最困难的事情,因为它违背了我们根深蒂固的直觉。

我们不应该假设集合不会改变。我们的本能可能导致我们认为这些事情是不可改变的。

例如,如果 车管所 向 人口普查局 提供一份司机名单,这似乎是合理的。我们认为 List<Driver> 是一个 List<Person> ,假设 Driver 是 Person 的子类型。事实上,被递交的应该是司机名单的副本,否则,人口普查局可能会在名单上增加新的非司机的人口记录从而破坏了车管所的记录。

为了应对这种情况,我们要考虑更灵活的泛型类型。到目前为止,我们所见到的规则是相当严格的。

                                                                                  

<< 定义简单泛型 · 目录 · 通配符 >>

本文译自:https://docs.oracle.com/javase/tutorial/extra/generics/subtype.html

转载于:https://my.oschina.net/tita/blog/2886564

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值