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

  • 相关阅读:
    [JAVA] 冻结Excel的第一行或第一列
    [SoapUI] 比较两个不同环境下的XML Response, 从外部文件读取允许的偏差值,输出结果到文本文件
    [Study] 通过游戏学编程的网站
    [SoapUI] SoapUI+Groovy中"org.apache.xmlbeans.XmlException: error:
    [SoapUI] 通过Groovy写文本文件
    [SoapUI] context.expand 和 groovyUtils.getXmlHolder 有什么不一样
    Codeforces Round #355 (Div. 2) C 预处理
    Codeforces Round #355 (Div. 2) B
    Codeforces Round #355 (Div. 2) A
    Codeforces Round #324 (Div. 2) D
  • 原文地址:https://www.cnblogs.com/alway-july/p/7646531.html
Copyright © 2011-2022 走看看