四千岁爷 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 labelme打不开怎么办
  • ¥35 按照图片上的两个任务要求,用keil5写出运行代码,并在proteus上仿真成功,🙏
  • ¥15 免费的电脑视频剪辑类软件如何盈利
  • ¥30 MPI读入tif文件并将文件路径分配给各进程时遇到问题
  • ¥15 pycharm中导入模块出错
  • ¥20 Ros2 moveit2 Windows环境配置,有偿,价格可商议。
  • ¥15 有关“完美的代价”问题的代码漏洞
  • ¥15 请帮我看一下这个简易化学配平器的逻辑有什么问题吗?
  • ¥15 暴力法无法解出,可能要使用dp和数学知识
  • ¥15 wpf通过绑定控件自身的值,来实现背景颜色的切换