我有以下方法:
public static <T> T[] toArray(Iterable<? extends T> iterable) {
return (T[]) StreamSupport.stream(iterable.spliterator(), false).toArray();
}
Run Code Online (Sandbox Code Playgroud)
我的 IDE 告诉我存在未经检查的强制转换。一般来说,我理解错误消息,但我无法理解为什么应该检查强制转换,因为 iterable 具有与我用于强制转换的相同类型。有人可以向我解释一下吗?
但我不明白为什么要检查演员阵容
经过检查的强制转换会产生checkcast字节码指令。例如:
String s = (String) someObject;
Run Code Online (Sandbox Code Playgroud)
在泛型的情况下,checkcast无法插入指令,因为代码中的该点没有已知的类型:a检查的类型checkcast被静态写入字节码;但你的方法必须适用于所有类型。因此,checkcast这里不能添加任何内容。
警告是编译器表达“我不能确定,但这里看起来有点可疑”的方式。事实上,确实有一些可疑的地方,但问题并没有出现在这段代码中。
假设您将此方法称为如下:
Integer[] ints = toArray(iterableOfInts);
Run Code Online (Sandbox Code Playgroud)
实际上会在调用站点插入经过检查的强制转换(由编译器插入):
Integer[] ints = (Integer[]) toArray(iterableOfInts);
Run Code Online (Sandbox Code Playgroud)
这将在运行时失败,因为Object[]无法转换为Integer[]. 但失败发生在这里,而不是toArray方法上。
解决这个问题的正确方法是提供一些东西来创建T[]:
public static <T> T[] toArray(Iterable<? extends T> iterable, IntFunction<T[]> arraySupplier) {
return StreamSupport.stream(iterable.spliterator(), false).toArray(arraySupplier);
}
Run Code Online (Sandbox Code Playgroud)
Iterable<? extends T>是一个合适的参数类型,因为它允许您创建超类型的数组:
Integer[] integers = toArray(iterableOfInts, Integer[]::new);
Object[] objects = toArray(iterableOfInts, Object[]::new);
Run Code Online (Sandbox Code Playgroud)