泛型

Think in java P478

因为擦除移除了类型信息,所以,可以用无界泛型参数调用的方法只是那些可以用Object调用的方法,如果能将这个参数限制为某个类型的子集,那么你就可以使用这个类型调用方法。

interface HasColor { java.awt.Color getColor(); }
class Colored<T extends HasColor> {
    T item;
    Colored(T item) { this.item = item; }
    T getItem() { return item; }
    java.awt.Color color() { return item.getColor(); }
}
class Dimension { public int x, y, z; }
//extends 类应该先放在前面,接口随后
class ColoredDimension<T extends Dimension & HasColor> { T item; ColoredDimension(T item) { this.item = item; } T getItem() { return item; } java.awt.Color color() { return item.getColor(); } int getX() { return item.x; } int getY() { return item.y; } int getZ() { return item.z; } }

特殊行为:可以向导出类型的数组赋予基类型数组的引用。

class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Apple {}
class Orange extends Fruit {}
public class CovariantArrays {
    public static void main(String[] args) {
        Fruit[] fruit = new Apple[10];
        fruit[0] = new Apple(); // OK
        fruit[1] = new Jonathan(); // OK
// Runtime type is Apple[], not Fruit[] or Orange[]:
        try {
// Compiler allows you to add Fruit:
            fruit[0] = new Fruit(); // ArrayStoreException
        } catch(Exception e) { e.printStackTrace(); }
        try {
// Compiler allows you to add Oranges:
            fruit[0] = new Orange(); // ArrayStoreException
        } catch(Exception e) { e.printStackTrace(); }
    }
}

但是实际上的数组类型是Apple[],你应该智能在其中放置Apple和Apple的子类,所以当你放置Fruit时,程序会报错ArrayStoreException。

泛型的主要目标之一是将这种错误检测移入到编译期。

       List< Fruit> flist = new ArrayList<Apple>();

这句话编译错误,将这种错误提前到了编译期。

public static void main(String[] args) {
        List< ? extends Fruit> flist = new ArrayList<Apple>();
        flist.add(new Apple());//报错
        flist.add(new Fruit());//报错  
     flist.add(new Obeject());//报错
flist.add(null); Fruit fruit = flist.get(0); }

List<? extends Fruit> flist   表示“具有任何从Fruit基础的类型的列表",但是,这实际上并不意味着这个List将持有任何类型的Fruit,这样这个flist唯一的限制是要持有某种的Fruit或Fruit的子类型,但你实际上并不关心它是什么,那么你能用这样的List做什么呢。

 List< ? super Fruit> flist = new ArrayList<Fruit>();
        flist.add(new Fruit());
        flist.add(new Apple());
        flist.add(new Object());//报错    
        flist.indexOf(new Apple());
        Fruit fruit = flist.get(0);//报错

List<?  super Fruit> flist  表示”持有从Fruit导出的某种具体类型“,向其中添加Fruit和Fruit的子类型是安全的。Fruit是下界,添加Object不是安全的。

原文地址:https://www.cnblogs.com/alway-july/p/7646531.html