java - Effective Java - Item 25 - Generics class cast exception 混合列表和数组

标签 java arrays list generics effective-java

我正在阅读 Joshua Bloch 的 Effective Java 第二版,第 25 项(第 122 页)。当您进一步阅读本章时,您会看到作者编写了以下代码:

// Naive generic version of reduction - won't compile!
static <E> E reduce(List<E> list, Function<E> f, E initVal) {
    E[] snapshot = list.toArray(); // Locks list
    E result = initVal;
    for (E e : snapshot)
    {
        result = f.apply(result, e);
    }
    return result;
}

然后作者声明编译器不会编译它,因为您需要在赋值 E[] snapshot = list.toArray(); 所在的行添加一个显式转换,结果在这个 E[] snapshot = (E[]) list.toArray(); 上,在这之后你会得到一个警告说有 [unchecked ] 未经检查的转换


问题 1:我知道这本书考虑到了 Java 6 之前的变化(我们现在差不多是 Java 8)。但是,我写了同样的方法,从编译中得到了同样的错误。这是因为我需要添加显式转换。但是没有警告。那么这个警告是关于什么的?


问题 2:作者声明以下方法可行,但事实证明它不是类型安全

With minor modifications, you could get it to throw a ClassCastException on a line that doesn't contain an explicit cast.

好的,我明白了...但是我怎样才能让它抛出 ClassCastException


我在这篇文章中留下了一个准备运行的例子,如果你想自己检查一下:

import java.util.Arrays;
import java.util.List;

public class Main
{

    public static void main(String[] args)
    {
        List<Integer> ints = Arrays.asList(10,20,30);
        Integer result = reduce (ints,new Function<Integer>() {

            @Override
            public Integer apply(Integer arg1, Integer arg2)
            {
                return arg1 + arg2;
            }
        },0);
        System.out.println(result);
    }

    static <E> E reduce(List<E> list, Function<E> f, E initVal)
    {
        E[] snapshot = (E[]) list.toArray(); // Locks list
        E result = initVal;
        for (E e : snapshot)
        {
            result = f.apply(result, e);
        }
        return result;
    }

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

最佳答案

E[] snapshot = list.toArray();

list.toArray()返回 Object[] 而不是 E[]。所以你需要在那里进行显式转换。但是这样的显式(或动态)转换的存在意味着编译器无法保证那里的类型安全。相反,您是在告诉编译器一切正常,并且在运行时它实际上是一个 E[]。因此,它会警告您 - unchecked cast。请注意,如果编译器能够保证那里的类型安全,那么它将在那里进行静态/检查转换(由编译器本身隐式执行)。

关于java - Effective Java - Item 25 - Generics class cast exception 混合列表和数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23713350/

相关文章:

java - 一个程序中的多个 JVM 实例

java - 将异常记录到数据库中

c++ - 大数组上的段错误

python - 如何填充表格中缺失的元素?

c# - 过滤列表条目

java - JList 不显示我的组合框中新添加的元素

java - 请求不适用于 HttpURLConnection 但适用于其他 HTTP 客户端

c++ - 在递归/另一个函数中返回静态/普通数组

arrays - 矩阵中的累积和

python - 将数据框转换为python中的列表列表