zoukankan      html  css  js  c++  java
  • 泛型

    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不是安全的。

  • 相关阅读:
    使用数字进行字符遍历
    注意:C++中double的表示是有误差的
    ER模型到关系模型的转换规则
    SQL中查询优化的主要策略
    分解成3NF保持函数依赖且为无损连接的算法
    函数依赖集闭包、属性集闭包、超键、候选键和最小函数依赖集的求法。
    分解成3NF的保持函数依赖的分解算法:
    模式分解是否为无损连接的判断方法
    字符串处理技巧
    sort+结构体实现二级排序
  • 原文地址:https://www.cnblogs.com/alway-july/p/7646531.html
Copyright © 2011-2022 走看看