通配符编译时错误

时间:2012-06-16 11:24:15

标签: java generics

在泛型中查看此示例:

// abstract class   
public abstract class Shape {
    public abstract void draw(Canvas c);

}

//implementation of shape class
public class Rectangle extends Shape {
    private int x, y, width, height;
    public void draw(Canvas c) { ... }
}

//function to add rectangle object in a list
public void addRectangle(List<? extends Shape> shapes) {
    shapes.add(0, new Rectangle()); // compile-time error!
}

为什么这是编译错误?我无法弄清楚作为形状的子类的类型列表中的形状,矩形是Shape的子类。

请帮我弄清楚这个问题。

2 个答案:

答案 0 :(得分:3)

这是因为List< ? extends Shape >表示传递的真实对象可能被声明为List<Rectangle>List<Circle>

如果你试图将一个矩形插入到一个真正有问题的圆圈列表中。

要使插入成功,您需要使用super,例如List< ? super Shape >

这意味着传递给此函数的真实对象可能只被声明为List<Shape>List<Object>。这样的列表肯定可以包含矩形和圆形(嘿,在后一种情况下,甚至苹果和橘子)。

答案 1 :(得分:3)

完全示例在Java tutorial

中进行了解释
  

与往常一样,使用灵活性需要付出代价   通配符。这个价格是现在写入shapes是非法的   在方法体内。例如,这是不允许的:

public void addRectangle(List<? extends Shape> shapes) {
    // Compile-time error!
    shapes.add(0, new Rectangle());
}
     

您应该能够弄清楚为什么不允许上面的代码。第二个参数的类型   shapes.add()? extends Shape - Shape的未知子类型。以来   我们不知道它是什么类型,我们不知道它是否是超类型   Rectangle;它可能是也可能不是这样的超类型,所以它不安全   在那里传递Rectangle