我们在学习java的继承规则时,已经知道任何需要父类型的地方,都可以被替换成子类型,现在我们有如下类的继承结构:
// 子类Student可以转换成父类Person
Student student = new Student();
Person person = student;
然而泛型机制规定如下的转换是错误的:
// Erro: Type mismatch: cannot convert from Result to Result
Result re_student = new Result(new Student(), new Student());
Result re_person = re_student;
在泛型机制里无论S和T这两个类是什么关系,Result和Result
我们假设上述的泛型转换是成功的,那么我们就可以通过re_person的引用,将Teacher类的相关信息设置到Result
(一) 通配符类型------上界通配符 extends T>
为了解决泛型这种使用起来的不便性,java泛型的设计者们引入了通配符"?"。
比如Result extends Person>表示任何泛型Result类型,它的类型参数是Person以及Person的子类,如Result
我们将上述的泛型转换改为如下形式:
// Result extends Person>是Result的父类型
Result re_student = new Result(new Student(), new Student());
Result extends Person> re_person = re_student;
这种形式的转换就是正确的,
我们称
extends Person>为上界通配符。
然而使用上界通配符也带来了一些副作用:
我们看如下的代码:
public static void main(String [] args){
// Result extends Person>是Result的父类型
Result re_student = new Result(new Student(), new Student());
Result extends Person> re_person = re_student;
Person person = re_person.getCode();
//Error:The method setCode(capture#2-of ? extends Person) in the type Result is not
//applicable for the arguments (Student)
re_person.setCode(new Student);
}
看起来域的访问器setCode()方法无法使用
re_person.setCode(new Student);// Error
Result extends Person>的方法看起来是如下这样的:
? extends Person getCode() {
return code;
}
void setCode(? extends Person code) {
this.code = code;
}
(二) 通配符类型------下界通配符 super T>
在上面中我们说,当使用上界通配符 extends T>时,只能get数据而不能set数据;而下界通配符 super T>刚好相反,当使用下界通配符时,只能set数据而不能get数据。
super Student> 表示将通配符限制为Student或者及其超类,如下图所示:
当使用Result super Student>下界通配符时,其方法看起来是这样的:
? super Student getCode() {
return code;
}
void setCode(? super Student code) {
this.code = code;
}
对于set操作我们已经知道形式参数是Student或者Student的超类
对于get操作 我们只知道返回值是Student或者Student的超类 但具体是什么类型我们不知道 所有我们无法
给具体的类进行赋值;只能赋值给Object对象
public static void main(String [] args){
// Result super Student>为下界通配符
Result re_student = new Result(new Student(), new Student());
Result super Student> sre_student = re_student;
// Error:The method setCode(capture#4-of ? super Student) in the type Result is not
// applicable for the arguments (Person)
sre_student.setCode(new Person());
// right operation
// 对于set操作我们已经知道形式参数是Student或者Student的超类
// 那么我们就可以使用小于等于Student粒度的类型来传递参数
sre_student.setCode(new Graduate());
sre_student.setCode(new Master());
// Error:Type mismatch: cannot convert from capture#5-of ? super Student to Student
// 对于get操作 我们只知道返回值是Student或者Student的超类 但具体是什么类型我们不知道 所有我们无法
// 给具体的类进行赋值;只能赋值给Object对象
Student student = sre_student.getCode();
// right operation
Object object = sre_student.getCode();
}
extends T>:上界通配符 只能取数据而不能写入数据
super T> : 下界通配符 只能写入数据 取数据只能赋值给Object
如果你既想要获取数据,又要写入数据,那么你不能使用通配符类型变量,你可以尝试使用固定的类型变量T,如果还不能解决你的问题,
那么不建议你使用泛型解决你的这个问题。