未经检查的演员阵容有什么问题?

St.*_*rio 15 java

我正在阅读J. Bloch的有效Java,现在我在数组与列表部分.以下是他提供的未经检查的演员的示例:

interface Function<T> {
    T apply(T arg1, T arg2);
}

public class Main{
    public static void main( String[] args ){
        Function<String> f = null;
        List<String> str = Arrays.asList("asd");
        //staff
        reduce(str, f, ""); //E's deduced to String. Where is type-unsafe?
    }
    static <E> E reduce(List<E> list, Function<E> f, E initVal) {
        E[] snapshot = (E[]) list.toArray(); // Unchecked cast
        E result = initVal;
        for (E e : snapshot)
            result = f.apply(result, e);
        return result;  
    }
}
Run Code Online (Sandbox Code Playgroud)

他说这种方法不是类型安全的,我们可以轻松搞定ClassCastException.但我不知道怎么做.哪里是类型不安全的,类型变量E将始终推导为适当的类型,因此我们不担心class-cast-exeption.

你不能举一个抛出的例子ClassCastException吗?

Tag*_*eev 13

没有编译时保证list.toArray()会返回类型数组E[].而且它几乎总是返回一个类型的数组Object[].因此,根据此阵列的后续用法,您可能拥有ClassCastException.例如,请考虑以下代码:

public static void main( String[] args ){
    List<String> str = Collections.singletonList("asd");
    String[] array = test(str);
}

static <E> E[] test(List<E> list) {
    E[] snapshot = (E[]) list.toArray(); // Unchecked cast
    return snapshot;
}
Run Code Online (Sandbox Code Playgroud)

在这里返回此E[]数组,接收器期望返回该数组String[].但实际上它是Object[]数组,因此在返回的泛型类型被隐式转换为后,您将获得ClassCastExceptionin main方法String[].

在您的代码中,您可以确保以安全的方式使用该数组.但编译器不够聪明,无法进行此分析,所以它只是警告你.