java泛型的类型擦除

泛型是JDK1.5时添加的,为了向前兼容,同时不对JVM进行大改,泛型在编译和运行期会擦除类型,这就会导致一些问题。

以数组为例:

String[] s = String[5];
Object[] o = s;
o.add(Object());

我们看这段代码,String数组是不能够添加Obect类型的对象的,运行时数组的具体类型是知道的,所以运行时会报错,编译前检查时不报错。

再来看泛型集合:

List<String> s = ArrayList<>();
List<Object> o = s;
o.add(Object());

由于类型擦除,运行期间并不知道o的具体类型,所以无法报错,只能放到编译前检查时报错。

java中是没有完全的逆变、协变的,List<String>不是List<Object>的子类型,为了解决这个问题,就引入了通配符的概念。

extends只能get,不能set:

List<String> s = ArrayList<>();

Object f(List<? extends Object> o) {
    o.add("ss"); //编译前检查会报错,由于o的具体类型不知道,只知道是Object的某个子类,不一定是String,所以添加string会报错。
    return o.get(0); //Object类型
}

f(s);


super只能set,不能get:

List<Object> o = ArrayList<>();

void f(List<? super String> s) {
    s.add("ss"); //正确。
    s.get(0); //没问题
    String temp = s.get(0); // 编译前检查会报错,类型不对
}

f(s);

总结:

无论是数组还是集合,都不能随便使用,无非是编译前还是运行时报错的问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值