java泛型(恶心)

一.术语较多

泛型类型 (泛型)                               :List<E>

泛型方法                                         :static <E> List<E> asList(E[] a)

原始类型(原生态类型)(raw type): List<E> 对应的原始类型就是 List

参数化类型                                     :List<String> 

形式类型参数                                 :List<E>的E

实际类型参数(类型参数的实例)      :List<String> 的 String

type of                                             :<>

通配符                                              :

二.注意

规定:Father是son的父类。

 1.形式类型参数指定为Father,传入子类,自动向上转型。

List<Father> list = new ArrayList<>();
list.add(new Son());

   形式参数指定为Son,传入父类,显示强制向下转型。

List<Son> list = new ArrayList<>();
list.add((Son) new Father());

2.泛型类型转换为原始类型,编译器对实际类型参数无法检测了。

List<Father> before = new ArrayList<>();
before.add(new Father());
        
List after = before;
after.add("hello world");

before添加的是对象,将before赋值给原始类型after后,
检测不到实际类型参数Father的存在,就添加了字符串对象。
这是不安全的操作。

3.List<? extends Father>:只能get 不能add

原因:

不知道具体类型参数是什么,也就不知道具体泛型类的内部元素是什么,所以add的值不能保证向下转型成功。

但是上限是Father类型,返回值用Father来接受一定没问题。

4.List<? super Father>     :  只能add 不能get

原因:

不知道具体类型参数是什么,但是指定了最低限度是Father类型,也就是实际List内部存储的是Father以及Father超类类型。add的时候有一个要求:只能设置Father 以及 Father的子类。因为一定能保证向上转型。

但是返回值是不能确定的,如果实际返回的是Father的父类对象,拿Father来接收,会抛出异常。

三.疑惑

看Arraylist源码看到一处代码:

E elementData(int index) {
    return (E) elementData[index];
}

 上面类型擦除之后不就变成:

Object elementData(int index) {
    return (Object) elementData[index];
}

 那强转有什么意义呢?而且,在下面我们实际使用的时候,是怎么直接可以赋值给String变量的呢?

实际使用:

ArrayList<String> list = new ArrayList<String>();
list.add("hello");

String s = list.get(0);

解答:

1.编写(E)的意义:原来这是编译期时编译器的类型检查,在代码编译时,编译器认为E是真实存在的类型,就好比我们使用时传入的String类型,所以我们需要进行强转,但是当按下运行编译的那一刻,这个E就会被擦出了。

2.如何直接赋值的呢?原来编译器会对代码编译为字节码的时候做手脚,会加上检查类型转换的字节码指令

附加:

就拿上面实际使用的例子生成的字节码:

可以看到红色框框的checkcast指令,引用了常量表中的String类型。实际对象的类型信息是可以通过对象头中的class指针获取。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值