Fimaly的get方法返回的是一个Object,为什么它不返回下限类型Son呢?
它所引用的对象类型只能是下限类型和下限类型的子类,那么返回的时候
将引用的类型转成下限类型返回是合理的呀,为什么要返回Object?public class GenericLowerBound {
        public static void main(String[] args) {
Family<? super Son> g = new Family<Father>();

/*将产生编译时错误,只能添加下限类型及以下的类型对象*/
//g.add(new Father());

g.add(new Son());
Son s = (Son)g.get();
System.out.println(s);

g.add(new GrandSon());
GrandSon gs = (GrandSon)g.get();
System.out.println(gs);
    }
}
class Family<T> {
    private T t;
    public void add(T t) { this.t = t; }
    public T get() { return t; }
}
class Father {
    public String toString() { return "Father"; }
}
class Son extends Father {
    public String toString() { return "Son"; }
}
class GrandSon extends Son {
    public String toString() { return "GrandSon"; }
}

解决方案 »

  1.   

    1.<? extends T>首先你很容易误解它为继承于T的所有类的集合,这是大错特错的,相信能看下去你一定见过或用过List<? extends T>吧?为什么我说理解成一个集合是错呢?如果理解成一个集合那为什么不用List<T>来表示?所以<? extends T>不是一个集合,而是T的某一种子类的意思,记住是一种,单一的一种,问题来了,由于连哪一种都不确定,带来了不确定性,所以是不可能通过add()来加入元素。你或许还觉得为什么add(T)不行?因为<? extends T>是T的某种子类,能放入子类的容器不一定放入超类,也就是没可能放入T。2.<? super T>这里比较容易使用,没<? extends T>这么多限制,这里的意思是,以T类为下限的某种类,简单地说就是T类的超类。但为什么add(T)可以呢?因为能放入某一类的容器一定可以放入其子类,多态的概念。网上摘的
      

  2.   

    假设Father extends GrandFather,并且允许g.add(Son的父类对象)
    那么Family<? super Son> g = new Family<Father>();
    Family<? super Son> g2 = new Family<GrandFather>();都正确
    则调用g.add(new GrandFather()),父类不能自动转为子类,错误
      

  3.   

    泛型中对类型的检测是在“编译阶段”,在“运行阶段”依然是以Object类型进行处理的,所以会出现你说的结果,如果对这个论点有质疑,你可以用反射来测试一下。
      

  4.   

     
    这里的意思是,以T类为下限的某种类,简单地说就是T类的超类。但为什么add(T)可以呢T类为下限的某种类,应当是T类的子类,而不是T类的超类啊,呵呵·
      

  5.   

    你的回答和我的提问不占边,? super T 是引用T的某一个超类,add方法只能添加T和T的子类,这些都没什么问题,这我也知道,我问的是get,为什么返回的是Object,它返回T类型会有错吗?没有吧
      

  6.   

    刚开始我也是认为它是以Object的方式处理的,可是? extends T 它返回的却不是Object而是T
    这又是为什么呢?public class GenericBoundUpper {    public static void main(String[] args) {
    UpperFamily<? extends UpperFather> uf1 = new UpperFamily<UpperSon>();

    /*将产生编译时错误*/
    //uf1.add(new Object());
    //uf1.add(new Father());
    //uf1.add(new Son());
    //uf1.add(new GrandSon());

    uf1.add(null);

    UpperFamily<? extends UpperFather> uf2 = new UpperFamily<UpperSon>(new UpperGrandSon());
    /*返回的是上限类型*/
    UpperFather fa = uf2.get();
    System.out.println(fa);
        }
    }class UpperFamily<T> {
        private T t;
        public UpperFamily() { }
        public UpperFamily(T t) { this.t = t; }
        public void add(T t) {
    this.t = t;
        }
        public T get() { return t; }
    }
    class UpperFather {
        public String toString() { return "Father"; }
    }
    class UpperSon extends UpperFather {
        public String toString() { return "Son"; }
    }
    class UpperGrandSon extends UpperSon {
        public String toString() { return "GrandSon"; }
    }
      

  7.   

    如果你添加的是一个GrandFather对象,但是通过get()方法将它返回为Son对象,则会产生ClassCastException。子类可以自动转为父类对象,但反过来就不可以了。<? super T>表示传入的是T对象或T的父类对象,它们的公共父类只能是Object
      

  8.   

    问题是如果你添加一个GrandFather对象,它就已经产生编译时错误了,所以不存在返回一个比Son更高的对象呀,所以我才觉得奇怪它为什么不返回下限类型
      

  9.   

    大致明白你的意思了,以下面的代码为例,ArrayList<? super Son> data = new ArrayList<Father>();中
    实际是生成了一个ArrayList<Son的某个父类>的对象,并将其转为ArrayList<? super Son>,也就是说在实际操作中起作用的是ArrayList<Son的某个父类>,自然不能返回Son对象。
    import java.util.ArrayList;
    public class Test
    {
    public static void main(String[] args) throws Exception
    {
    ArrayList<? super Son> data = new ArrayList<Father>();
    data.add(new Son());
    data.add(new GrandSon());
    //Son s = data.get(0);
    Object obj = data.get(0);
    }
    }class GrandFather{}
    class Father extends GrandFather{}
    class Son extends Father{}
    class GrandSon extends Son{}
      

  10.   

    另外,如果允许返回Son对象,则下面的代码会出现问题(编译已通过)
    import java.util.ArrayList;
    public class Test
    {
    public static void main(String[] args) throws Exception
    {
    ArrayList<Father> father = new ArrayList<Father>();
    father.add(new Father());
    ArrayList<? super Son> data = father;
    //Son s = data.get(0);
    Object obj = data.get(0);
    }
    }class GrandFather{}
    class Father extends GrandFather{}
    class Son extends Father{}
    class GrandSon extends Son{}