java 泛型t get()_java 泛型(一)

我们在学习java的继承规则时,已经知道任何需要父类型的地方,都可以被替换成子类型,现在我们有如下类的继承结构:

e8cf848d321b8c050634eb75ae249270.png

// 子类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 re_student这个对象中,这显然是不允许的。

(一) 通配符类型------上界通配符 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>为上界通配符。

bf3b641990917e7a30ff26f4b9427832.png

然而使用上界通配符也带来了一些副作用:

我们看如下的代码:

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;

}

setCode的形参是? extends Person code,但是不知道具体是什么类型这样就无法传递特定的类型,也就无法调用setCode()方法了,毕竟通配符"?"不能匹配具体的任何类型。

而getCode()是能正常调用的,我们知道? extends Person代表的是Person的子类,这样我们就可以把get到的值转换成父类型Person。

(二) 通配符类型------下界通配符 super T>

在上面中我们说,当使用上界通配符 extends T>时,只能get数据而不能set数据;而下界通配符 super T>刚好相反,当使用下界通配符时,只能set数据而不能get数据。

super Student> 表示将通配符限制为Student或者及其超类,如下图所示:

d11c69e6e1226d2e0d7f6ed4e6d649cc.png

当使用Result super Student>下界通配符时,其方法看起来是这样的:

? super Student getCode() {

return code;

}

void setCode(? super Student code) {

this.code = code;

}

对于set操作我们已经知道形式参数是Student或者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,如果还不能解决你的问题,

那么不建议你使用泛型解决你的这个问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值