3

Joshua Bloch の「Effective Java 2nd edition」の項目 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();結果として this が発生しE[] snapshot = (E[]) list.toArray();その後、.[unchecked] unchecked cast


Q1: この本は Java 6 までの変更を考慮に入れていることを知っています (そして、現在 Java はほぼ 8 です)。ただし、同じメソッドを作成すると、コンパイルから同じエラーが発生します。これは、明示的なキャストを追加する必要があるためです。ただし、警告はありません。それで、その警告は何についてですか?


Q2: 著者は、次のメソッドが機能すると述べていますが、タイプ セーフではないことが判明しました。

ClassCastExceptionマイナーな変更により、明示的なキャストを含まない行で aをスローすることができます 。

わかりました、それはわかりました...しかし、どうすればそれをスローさせることができ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);
    }
}
4

4 に答える 4

0

Question2 については、以下のコードで作者を理解しようとしています。

発信者:

List<String> list = Arrays.asList("string");
reduce(list, new Function<String>() {
    @Override
    public String apply(String arg1, String arg2) {
        return "";
    }
}, "");

「減らす」方法:

static <E> E reduce(List<E> list, Function<E> f, E initVal) {
    // /*
    List<E> snapshot;
    synchronized (list) {
        snapshot = new ArrayList<>(list);
    }
    snapshot.set(0, 123);    // compile error here
    // */

    /*Object[] objs = list.toArray();
    objs[0] = 123;  // will cause ClassCastException on runtime
    E[] snapshot = (E[]) objs;*/
    E result = initVal;
    for (E e : snapshot) {
        result = f.apply(result, e);
    }
    return result;
}

「微修正あり」というほどではないかもしれませんが、適当な説明です。

于 2016-01-19T10:45:03.177 に答える