Which type safety would have lost, had Generics supported the sub-typing?
考虑一下这段代码:
1 |
这样做完全可以,
往前走,
1 2 3 4 5 6 |
如果第3行设计成功,我们最终会得到一个
这些都是数字。
我在一本书中看到这个,
Generics doesn’t support sub-typing because it will cause issues in
achieving type safety. That’s whyList is not considered as a
subtype ofList whereS is the super-type ofT
在上面讨论的这种特定情况下,哪种类型的安全性会丢失?第3行是否要成功编译?
1 2 | List<Long> listLong = new ArrayList<Long>(); List<Number> listNumbers = listLong; |
那么,
1 |
所以,您可以向该列表中添加一个双精度值。因此,
如果是这种情况,那么我们可以在
假设您现在正在插入
让我们用一个非抽象基类的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class Human { public string getName() { // ... } } public class Student extends Human { public void learn(Subject subject) { // ... } } public class Teacher extends Human { public void teach(Subject subject) { // ... } } |
在任何需要
所以,这不意味着我们也可以在预期使用
1 2 3 4 5 6 7 | public class Human { // ... public void join(Set<Human> party) { party.add(this); } } |
现在,如果Java允许一个EDCOX1的17度作为方通过,那么任何非EDCOX1、11、EDCOX1、10、s加入该方的尝试都必须在运行时失败。
作为一般规则,如果接收者(函数参数的被叫方,函数返回值的被叫方)希望将某些内容放入其中,则子类型的容器是不合适的,但如果接收者只想取出并使用这些内容,则可以接受。如果接受者想要取出并使用超类型的容器是不合适的,但是如果接受者只想把东西放进去,那么可以接受。因此,如果接收者都从集合中取出东西并将其放入集合中,那么他们通常需要一个固定类型的集合。
我们的
1 2 3 4 5 6 7 | public class Human { // ... public void join(Set<? super Human> party) { party.add(this); } } |
为了打开子类的可能性,有上界通配符:
1 2 3 4 5 6 7 | public class Teacher extends Human { public void teach(Subject subject, Set<? extends Student> schoolClass) { for (Student student : class) { student.learn(subject); } } } |
现在,如果我们将
你所指的概念是方差。
换言之,如果
EDCOX1的33Ω-和所有其他Java泛型*的答案是"无关的",即不变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class SuperType {} class Type extends SuperType {} class SubType extends Type {} List<Type> list = ... List<SuperType> superList = list; superList.add(new SuperType()); // no, we shouldn't be able to add a SuperType to list List<SubType> subList = list; SubType item = subList.get(0); // no, there's not necessarily only SubType items in list |
* Java使用"通配符"(EDCOX1(34))具有"使用站点"差异的概念。这将限制可以调用的方法。
1 2 3 4 5 | List<Type> list = ... List<? super SubType> wildcardList = list; wildcardList.add(new SubType()); // but...everything we get() is an Object |
或
1 2 3 4 5 | List<Type> list = ... List<? extends SuperType> wildcardList = list; SuperType item = wildcard.get(0); // but...it's impossible to add() |
仅供参考,有些语言有定义站点差异的概念,例如scala。因此,