反射 向集合插入异于声明泛型的数据

来源:4-3 泛型不仅仅是规定集合中的类型那么简单

TimelessPast

2021-03-13

    List<Integer> list = new ArrayList<>();
    list.add(1);
    // 通过反射 添加不同于该泛型的数据
    list.getClass().getMethod("add", Object.class).invoke(list, "abc");
    list.getClass().getMethod("add", Object.class).invoke(list, 1.2);

输出的时候 只有普通的for循环 打印出来才不抛出异常
如果使用增强for循环或者list.forEach(System.out::println); 就会有异常
这是什么原因

写回答

1回答

张勤一

2021-03-13

同学你好:

    普通的 for 循环是没有对容器中的元素做强制类型转换的,但是,像 foeEach 这样的语句,由于泛型的存在,它会考虑对元素进行强制类型转换再进行输出。可以查看那 ArrayList 的 forEach 源码找到答案:

@Override
public void forEach(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    final int expectedModCount = modCount;
    @SuppressWarnings("unchecked")
    final E[] elementData = (E[]) this.elementData;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        action.accept(elementData[i]);
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
}


    可以看到入参,以及 for 循环里的  accept,需要对每一个元素强转之后再去输出。所以,当 String 向 Integer 转换的时候,就可能会抛出 java.lang.ClassCastException。


    我是勤一,欢迎随时找我!

1
0

Java实操避坑指南 SpringBoot/MySQL/Redis错误详解

掌握业务开发中各种类型的坑,,Java web开发领域通用

466 学习 · 204 问题

查看课程