从字节码角度分析java泛型数组的问题

关于java的泛型数组这个问题,之前就有遇到过,不过当时以为是自己代码语法错误的问题,现在系统地对java的基础知识进行深入总结,才发现这个问题某种程度是和泛型的类型擦除机制有关,其实我觉得这个解释有它的道路但是还是比较勉强。下面我们从字节码角度试图去分析一下java某种意义上是不支持泛型数组原因

比如源码:

List<String>[]list3 = new ArrayList<String>[10];//错误定义格式

List<String>[]list3 = new ArrayList[10]; //正确定义格式

List<Long>l = new ArrayList<Long>();

                   l.add(99l);

                   Object[] o=list3;

                   o[0]=l;

                   list3[0].get(0).length();

字节码:

  java.util.List<java.lang.String>[]list3;

    descriptor: [Ljava/util/List;

    flags:

    Signature: #16                          //[Ljava/util/List<Ljava/lang/Strin

g;>;

        61: aload_0

        62: bipush        10

        64:anewarray     #29                 // class java/util/ArrayList

        67: putfield      #31                 // Fieldlist3:[Ljava/util/List;

        70: new           #29                 // class java/util/ArrayList

        73: dup

        74: invokespecial #33                 // Methodjava/util/ArrayList."<in

it>":()V

        77: astore_1

        78: aload_1

        79: ldc2_w        #34                 // long 99l

        82: invokestatic  #36                 // Methodjava/lang/Long.valueOf:(

J)Ljava/lang/Long;

        85: invokeinterface #42,  2          // InterfaceMethod java/util/List.

add:(Ljava/lang/Object;)Z

        90: pop

        91: aload_0

        92: getfield      #31                 // Fieldlist3:[Ljava/util/List;

        95: astore_2

        96: aload_2

        97: iconst_0

        98: aload_1

        99: aastore

       100: aload_0

       101: getfield      #31                 // Fieldlist3:[Ljava/util/List;

       104: iconst_0

       105: aaload

       106: iconst_0

       107: invokeinterface #48,  2          // InterfaceMethod java/util/List.

get:(I)Ljava/lang/Object;

       112: checkcast     #52                 // class java/lang/String

       115: invokevirtual#54                 // Methodjava/lang/String.length:

()I

       118: pop

--在代码中,我们通过巧妙的步骤用List<Long>对象填充到了List<String>[]数组中,注意红色部分,我们执行list3[0].get(0).length();时其实list3[0]的类型已经是List<Long>,所以list3[0].get(0)其实运行时得到的是Long类型对象,但是编译器是没这么聪明的,它还是遵循正常的类型擦除机制对get到的Object对象进行类型转换checkcast ,这样就会使我们代码运行时会爆出类型转换的异常。这种情况或许能作为解释java不支持泛型数组的一个理由。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值