java 泛型上下限_java泛型上下限

前言:

java的泛型上下限不是很好理解,尤其像我这种菜鸡。反反复复看了好几遍了...,真是...

一、简单的继承体系

classPerson{}class Student extendsPerson{}class Worker extends Person{}

二、泛型上限(extends 关键字)

public static void upperBound(List extends Person>list, Person p){//正确,因为null没有类型信息

list.add(null);//错误,因为list的参数类型可能是Person的子类list.add(p);①//成功获取

if(list.size() > 0){

Person pp= list.get(0);②

}

}

①处的错误在于list的参数类型是不确定的,其参数类型可能是 Person的子类,子类集合(List)不能添加父类的元素。测试如下:

public static voidtestUpperBound(){

ArrayList slist = new ArrayList();

Person p= newPerson();

upperBound(slist, p);//无法添加成功

}

如何解决泛型上限添加问题,可以使用泛型方法,如下:

public static void upperBound2(Listlist, T p){

list.add(p);

}

public static voidtestUpperBound2(){

ArrayList plist = new ArrayList();

Person p= newPerson();

Student s= newStudent();

upperBound2(plist, p);

upperBound2(plist, s);

}

也就是说,使用泛型上限add方法时,集合参数类型 和 元素参数类型 要一致,这样添加的时候才不会有矛盾。看一下eclipse中对upperBound2(plist, s);这个函数调用的提示,如下:

7850883962de3eb9400ab87562daa4aa.png

可见,T类型最终会解析为 泛型的最上限类型,Student s相应的向上转型。

接着说 ② 处,为什么能获取成功呢?泛型上限嘛,至少上限的类型是确定的,所有的上限类型的子类都可以进行向上转型,自然获取是不成问题了。

三、泛型的下限

public static void lowerBound(List super Student>list){

Person var= newPerson();//错误,list的参数类型可能是 Student,这样就不能添加父类Person了,所以 变量var的类型 必须是 Student或者 Student的子类list.add(p);①//正确

Student s = newStudent();

list.add(s);

}

public static voidtestlowerBound(){

ArrayList list = new ArrayList();

lowerBound(list);

}

①处添加失败,告诉我们,泛型下限使用add方法添加元素时,元素的参数类型必须是 下限 或者 下限的子类型。否则会出现子类集合添加父类元素。

public static void lowerBound2(List super Person>list){

Person p= newPerson();

list.add(p);//获取,不能编译

Person as =list.get(0);①

}

public static voidtestlowerBound2(){

ArrayList list = new ArrayList();

lowerBound2(list);

}

①处获取失败了,我们看一下eclipse提示我们该怎么办?

2c777c714b6ff6ef9a064d8e3441fd97.png

将 第二个方法 将"as"的类型更改为"Object"  和 泛型的下限 结合一下考虑一下,add(e)方法在正确添加后,都会成为Object对象,在使用get(index)方法时,会转换为

? super Person类型(可能是Person类型,也可能是Person的父类类型,甚至是Object),执行Person as = list.get(0),那么就有了 向下转型。java中无法保证向下转型是安全的。所以①处不能编译。

四、泛型上限最常见的一个应用

List plist = new ArrayList();

List slist = new ArrayList();

plist.addAll(slist);

831fa1b62dd0330619de5d361a62c336.png

五、泛型下限最常见的一个应用

Set set = new TreeSet(new Comparator() {

@Overridepublic intcompare(Person o1, Person o2) {return 0;

}

});

3a1b4452ea4f9399720acb2e546ce130.png

六、泛型上下限一个综合的例子

注:个人瞎掰的...,就是将上面两个例子结合在一起!

Set set = new TreeSet(new Comparator() {

@Overridepublic intcompare(Person o1, Person o2) {return 0;

}

});

List slist = new ArrayList();

List wlist = new ArrayList();

set.addAll(slist);

set.addAll(wlist);

接下来,研究一下泛型的擦除...

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值