public class GenericTest<T> { private T foo; public T getFoo() {
return foo;
} public void setFoo(T foo) {
this.foo = foo;
} public static void main(String[] args) { GenericTest<String> ge = new GenericTest<String>(); ge.setFoo("hello"); GenericTest<? extends Object> ge2 = ge;
//1.编译正确 GenericTest<Object> ge3 = ge;
//2.为什么编译错误 ge2.setFoo(new Integer(1));
//3.为什么编译错误

ge2.setFoo(null);

}
}泛型高阶 编译错误

解决方案 »

  1.   

    1.? extends只能get,不能set;? super 只能set,不能取。
    2.泛型相等不存在继承关系
      

  2.   

    因为ge2中的泛型变量为? extends Object,也就是相当于告诉编译器,我知道这个GenericTest类中放的是一个继承Object的类,但我并不能确定该放哪个Object的子类,而楼主你在2中自作主张的放了一个Integer,这个时候编译器并不能通过,因为编译器也不知道这个特定的类是不是Integer,因为它还有可能是String等其他的类,所以这个时候就不会让你通过编译。
          像这种情况下,只有未被泛化的方法才能被ge2调用.当然null也可以被使用,只是没有意义.解决这个问题通常是用? super T来代替? extends T
      

  3.   

    这个地方,你需要弄明白泛型的继承关系和通配符的作用。
    其中GenericTest<Object>和GenericTest<String>之间不存在继承关系,所以不能相互赋值,不过两者都可以认为是GenericTest<T>的子类。
    通配符<? extends T>的作用是为了编程方便,是我们在编程的过程中可以直接使用T接口中的方法。
    你的第一句虽然没有错误,但是没有任何意义的,是把一种确定关系,转变成了一种不确定关系。举一个例子,现在有一袋黄豆,你已经知道是黄豆,但是别人问你是什么,你却告诉别人是黄豆也可能是绿豆。
    第二句中是把一种不确定关系赋值给一种确定关系,显然就有可能出问题。比如现在一袋豆子,不知道是黄豆还是绿豆,但你非要断言它是黄豆,显然是不合适的。
    你的第三句就更不合适了,接着上一个例子,现在不确定袋子里是黄豆还是绿豆,但你却要把大米放到袋子里面。