反射 向集合插入异于声明泛型的数据
来源: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。
我是勤一,欢迎随时找我!
10
相似问题