四千岁爷 2022-01-08 21:54 采纳率: 66.7%
浏览 17
已结题

泛型强转类型之后取数据的一个疑问?

开发环境JDK8:

java version "1.8.0_301"
Java(TM) SE Runtime Environment (build 1.8.0_301-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.301-b09, mixed mode)

源码如下,注意源码是可以编译通过的,你们先运行一下代码,我怕我的描述你们没看懂,[\苦笑]。

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class ListReflectDemo2 {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        
        ArrayList<String> listStr = new ArrayList<String>();
        listStr.add("只能添加String类型");
        
        Class c2 = listStr.getClass();
        Method m= c2.getMethod("add", Object.class);
        m.invoke(listStr, 20);//注意listStr只能添加String类型,我们现在可以通过反射的手段绕过编译器给他加一个整形进去
        System.out.println("注意整形已经添加进去了,List的元素个数为:->       " + listStr.size());
        
        System.out.println();
        
        Object obj = listStr;
        ArrayList<Boolean> listTest = (ArrayList<Boolean>)obj;
        System.out.println("看看listTest的Class类型到底是什么类型:->    " + listTest.getClass());
        System.out.println("我想得到一个Boolean类型,但是得到确实String类型,这是为什么,为什么这里没报错?:->    " + listTest.get(0));
        System.out.println("我想得到一个Boolean类型,但是得到确实String类型,这是为什么,为什么这里没报错?:->    " + listTest.get(1));
        System.out.println("上面没报错就很奇怪,一定要搞明白");
        
        System.out.println();

        System.out.println("下面的会报错我能理解,上面的没报错我就不能理解?");
        System.out.println("listStr的toString方法,注意整形也可以输出出来:    " + listStr.toString());
        System.out.println("看看listStr的Class类型到底是什么类型:->    " + listStr.getClass());
        //Integer in = list2.get(1);编译直接就报错了
        System.out.println(listStr.get(1));//这里会什么又会报错了,因为lis2认为20是String类型的,结果就报错了,java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    }
}

我的疑问如下截图:
第一个疑问:这里为什么不会报错?

img

第二个疑问:这里又为啥会报错了?

img

字节码截图:为什么最后一个get方法会有一个checkcast指令啊?

img

背景知识:

我知道Java的泛型其实是一个语法糖,只在源码中存在,编译成功之后的class文件里面泛型就会被擦除掉。在class文件里面是不存在ArrayList这种类型的,只存在ArrayList这种类型。

  • 写回答

2条回答 默认 最新

  • soar3033 2022-01-08 22:45
    关注

    因为你上面的那个在get方法前有字符串和“+”,所以jvm直接把返回的true或false转换了。而后面那个没有,所以不转换,就是bool类型,就报错了。下面你要是加上字符串和加号,一样不报错

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 1月17日
  • 已采纳回答 1月9日
  • 创建了问题 1月8日

悬赏问题

  • ¥15 对于squad数据集的基于bert模型的微调
  • ¥15 为什么我运行这个网络会出现以下报错?CRNN神经网络
  • ¥20 steam下载游戏占用内存
  • ¥15 CST保存项目时失败
  • ¥15 树莓派5怎么用camera module 3啊
  • ¥20 java在应用程序里获取不到扬声器设备
  • ¥15 echarts动画效果的问题,请帮我添加一个动画。不要机器人回答。
  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事: