泛型高阶:解释出现的错误!
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.? extends只能get,不能set;? super 只能set,不能取。
2.泛型相等不存在继承关系
------解决方案--------------------因为ge2中的泛型变量为? extends Object,也就是相当于告诉编译器,我知道这个GenericTest类中放的是一个继承Object的类,但我并不能确定该放哪个Object的子类,而楼主你在2中自作主张的放了一个Integer,这个时候编译器并不能通过,因为编译器也不知道这个特定的类是不是Integer,因为它还有可能是String等其他的类,所以这个时候就不会让你通过编译。
像这种情况下,只有未被泛化的方法才能被ge2调用.当然null也可以被使用,只是没有意义.
解决这个问题通常是用? super T来代替? extends T
------解决方案--------------------这个地方,你需要弄明白泛型的继承关系和通配符的作用。
其中GenericTest<Object>和GenericTest<String>之间不存在继承关系,所以不能相互赋值,不过两者都可以认为是GenericTest<T>的子类。
通配符<? extends T>的作用是为了编程方便,是我们在编程的过程中可以直接使用T接口中的方法。
你的第一句虽然没有错误,但是没有任何意义的,是把一种确定关系,转变成了一种不确定关系。举一个例子,现在有一袋黄豆,你已经知道是黄豆,但是别人问你是什么,你却告诉别人是黄豆也可能是绿豆。
第二句中是把一种不确定关系赋值给一种确定关系,显然就有可能出问题。比如现在一袋豆子,不知道是黄豆还是绿豆,但你非要断言它是黄豆,显然是不合适的。
你的第三句就更不合适了,接着上一个例子,现在不确定袋子里是黄豆还是绿豆,但你却要把大米放到袋子里面。