Why we can't do List<Parent> mylist = ArrayList<child>();
为什么我们做不到
1
| List<Parent> mylist = ArrayList<child>(); |
- nitpick:Parent/ Child隐喻是古怪的,当文明的传承的,因为我是一个describes的继承关系。(将你所说的A是一个ChildParent吗?)
- 因为A家族树的层次结构或是常常准备用于为一个analogy for Java A型的层次结构。尽管从semantically你有一点。
假设我们可以。那么这个程序就必须是好的:
1 2 3 4 5
| ArrayList<Banana> bananas = new ArrayList<Banana>();
List<Fruit> fruit = bananas;
fruit.add(new Apple());
Banana banana = bananas.get(0); |
很明显,这不是一个安全的类型-你已经结束了一个苹果在收集香蕉。
你能做的是:
1
| List<? extends Fruit> fruit = new ArrayList<Banana>(); |
这是安全的,因为编译器不会让您尝试添加到水果列表中。它知道这是某种水果的列表,所以你可以写:
1
| Fruit firstFruit = fruit.get(0); |
但它不知道它是一份什么水果的清单,并且确保你不会做错事。
请参见Java泛型常见问题解答的另一个解释。
- 我很喜欢这个解释。
- 乔恩,你刚才把我关于AlignmentAssigner的问题和这个联系起来了;我实现了扩展符号,它起作用了。一个问题是:当我将填充数组传递给扩展接口的实用方法时,该列表将类型更改为泛型。是否可以让一个方法扩展一个接口,处理实现该接口的数据,然后将其作为原始类型传递回?唯一的问题是,我不得不将新的泛型列表强制转换为使用我的实现类。
- @rainydaymatt:不,如果不使类型本身成为通用的,不。否则,您将如何保存关于您拥有的列表类型的信息?
- 这可能是您引用的常见问题解答:angelikalanger.com/genericsfaq/faqsections/&hellip;
- @杰克88:谢谢,编辑。
- 我完全不同意这种论点。将香蕉存储为水果是一回事;将list存储为list是另一回事。
- @安德鲁:我不知道你当时反对什么。我已经解释了为什么你不能把List当作List来对待。
- 在对原始问题的字面回答中,是的,您是正确的;但是,香蕉的实际用途(未说明但预期用途)是存储在一个列表中。
- @安德鲁:我看不出这个问题有什么迹象。这个问题明确地问为什么我们不能将ArrayList类型的值赋给List类型的变量。我的回答解释了这一点,并被接受了——是什么让你认为你比他们自己更了解OP的想法?
- 因为我怀疑他想做一些明智的事情,但却不完全理解它是如何工作的。为了解决这个问题,他想做的明智的事情是把香蕉储存在水果清单上,即使清单上有水果。你的回答让他不知道的是,他可以把香蕉从单子里抽出来,放到水果单子里。那么他的意图是有意义的,即使他的问题没有。
- @安德鲁:我觉得没有理由不认为手术就是他们所要求的。类似的问题被问了很多次。当一个问题被清楚地表达出来,并且答案被接受而没有进一步的评论时,我将避免试图对发问者进行二次猜测。仅仅因为你觉得问题写得很明显并不意味着提问者就这么做了。(现在还不清楚你在什么方面"完全不同意这一观点或论点"。)
- 你误会了我:我不是在猜测提问者。我是说你的论点不够有力。因此,"我完全不同意这种说法。"提问者总是做提问者总是做的事情。然而,你以一种狭隘的眼光回答了他的问题,你仍然看不见,或者至少不会承认。他要求的重点是学习,而不是有一个超文字的答案;他需要理解,而不仅仅是有一个公认的答案。不管怎样,我们现在在浪费时间。
- @安德鲁:"我不是在猜测提问者。"是的,你是。你在猜测他们除了问题之外还不清楚什么。除非你亲自知道手术,否则你就猜到了。"我是说你的论证不可靠,"哪一种推理?我的答案中的推理是可靠的,并且清楚地解释了为什么操作的代码不会也不应该编译,这就是他们所要求的。有一件事我们可以达成共识:这是在浪费时间。我对自己理解提问者在寻找什么的能力很有信心。
因为它们不是同一类型。假设您有另一个Parent的子类(Child2,出于论证的考虑),那么可以将Child2的一个实例放入List中,但类型不正确,无法将其放入List的实例中。协变继承是一个令人头疼的问题,在Java中只支持数组类型(因为它可能会导致奇怪的问题)。
应该是这样,因为我们可以做到:父级A=新子级();
编辑:等等,实际上它是工作的:
List list = new ArrayList();
List tmp = new ArrayList();
list.addAll(tmp);
List tmp2 = new ArrayList();
list.addAll(tmp2);
只是不支持直接强制转换。