如果在使用时泛型类时不传入泛型实参会出现警告,但是如果我们并不能确定其类型如何处理?第一种想法是传入Object类型的实参,但是实际上这种办法是行不通的。

public class Test {
    public void listTest(List<Object> c){
        for(int i=0;i<c.size();i++){
            System.out.println(c.get(i));
        }
    }
    public static void main(String[] args) {
        List<String> strList=new ArrayList<>();
        //编译不能通过,The method testList(List<String>) is undefined for the type Test
        //testList(strList);
    }
}

这是因为Java中List<string>并不是List<object>的子类,指定类型为Object传入参数类型只能是Object。</object></string>

为了解决这个需求,可以使用类型通配符。

public void listTest(List<?> c){
    for(int i=0;i<c.size();i++){
        System.out.println(c.get(i));
    }
}

List<?>表明他是任何泛型List的父类,现在任何的List类型都可以调用listTest()方法。上面的代码解决了不指定类型抛出警告的问题,在有的时候却会使代码臃肿:使用了泛型还要进行强制类型转换。我们也可以设定通配符上限,只代表某一类泛型的父类。

public abstract class shape {
    public abstract void draw(Canvas c);
}

public class Circle extends Shape {
    @Override
    public void draw(Canvas c) {
        System.out.println("在画布" + c + "上画个圈圈");
    }
}

public class Retangle extends Shape {
    @Override
    public void draw(Canvas c) {
        System.out.println("在画布" + c + "上画个块块");

    }
}

public class Canvas {
    public void drawAll(List<? extends Shape> shapes) {
        for (Shape s : shapes) {
            s.draw(this);
        }
    }
}

在并不知道受限制的通配符的具体类型时,不可以将Shape及其子类对象加入这个泛型集合中。

public void addRetangle(List<? extends Shape> shapes){
//        shapes.add(0, new Retangle());
}