英文:
Why do contravariant collections only allow Object instances to be retrieved?
问题
在下面的示例中,“Apple”是可以添加到数组的任何内容的超类型。在下面的示例中,“Apple”或其任何子类型都可以添加到列表中。然而,只允许检索“Object”实例。由于只允许添加Apple及其子类型,为什么Java不允许将值映射到“Apple”实例?
class Fruit {
@Override
public String toString() {
return "我是水果!!";
}
}
class Apple extends Fruit {
@Override
public String toString() {
return "我是苹果!!";
}
}
class AsianApple extends Apple {
@Override
public String toString() {
return "我是亚洲苹果!!";
}
}
public class GenericsExamples {
public static void main(String[] args) {
//苹果列表
List<Apple> apples = new ArrayList<Apple>();
apples.add(new Apple());
//我们可以将苹果列表分配给苹果篮子
List<? super Apple> basket = apples;
basket.add(new Apple()); //成功
basket.add(new AsianApple()); //成功
basket.add(new Fruit()); //编译时错误
basket.add(new Object()); //编译时错误
Object fruit1 = basket.get(0); //可行
Apple appleFruit = basket.get(0); //编译器错误
}
}
英文:
In the below example "Apple" is the super type of anything that can be added to the array. In the example below "Apple" or any of its subtypes are allowed to be added to the list. However only "Object" instances are allowed to be retrieved. Since only Apple and it's subtypes are allowed , why doesn't Java allow the values to be mapped to "Apple" instances?
class Fruit {
@Override
public String toString() {
return "I am a Fruit !!";
}
}
class Apple extends Fruit {
@Override
public String toString() {
return "I am an Apple !!";
}
}
class AsianApple extends Apple {
@Override
public String toString() {
return "I am an AsianApple !!";
}
}
public class GenericsExamples
{
public static void main(String[] args)
{
//List of apples
List<Apple> apples = new ArrayList<Apple>();
apples.add(new Apple());
//We can assign a list of apples to a basket of apples
List<? super Apple> basket = apples;
basket.add(new Apple()); //Successful
basket.add(new AsianApple()); //Successful
basket.add(new Fruit()); //Compile time error
basket.add(new Object()); //Compile time error
Object fruit1 = basket.get(0); //works
Apple appleFruit = basket.get(0); // compiler error
}
}
答案1
得分: 2
也许你误解了List<? super Apple>
的含义。通过它,你完全可以做如下操作:
List<? super Apple> apples = new ArrayList<Object>();
我现在肯定不能从apples
中获取Apple
对象,对吧?
因为在编译时Java并不知道apple
实际上是什么类型(是ArrayList<Object>
还是ArrayList<Apple>
?),所以它不允许你从中获取Apple
对象。
List<? super Apple>
的目的是允许你将任何类型的List
放入apples
变量中,只要该类型是Apple
或其父类。正因为如此,你可以将特定类型(Apple
或其子类)的对象放入此列表中,但从中获取的只能是Object
类型。
英文:
Perhaps you misunderstood what List<? super Apple>
means. With it, you can totally do something like this:
List<? super Apple> apples = new ArrayList<Object>();
I can certainly not get Apple
s from apples
now, can I?
Since Java doesn't know at compile time what apple
actually is (Is it a Arraylist<Object>
or ArrayList<Apple>
?), it can't allow you to get Apple
s out of it.
The point of List<? super Apple>
is to allow you to put any type of List
into the apples
variable, as long as that type is Apple
or one of its superclasses. Because of this, it is limited what you can put into this list (Apple
or its subclass) and what you can get out of it (Object
only).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论