3

Javaジェネリックは不変であるため、そのようなキャストを行うことは不可能です:

List<Object> li = (List<Object>)new ArrayList<Integer>();

しかし、次の 4 行目のコードでは、 from からList<Integer>toList<T>にキャストできます。ここでTは、任意の型を指定できます。なぜそのタイプのキャストが許可されているのですか?

チェックされていないキャストに関する警告が生成されることは知っていますが、ポイントは、このキャストはパラメーター化されたメソッド内で可能ですが、通常のコードでは不可能であるということです。ジェネリックは不変であることに注意してください。なぜそれが許可されているのですか? 通常のコードでは、意味をなさないものList<Integer>にしかキャストできず、他のキャストは違法です。List<Integer>それでは、4行目のようなキャストを許可するポイントは何ですか?

ジェネリック型はコンパイル時に削除され、 で終わることは知っていますが、これらの型を削除する前に、誰かが Integer を渡す場合にのみ受け入れられない限り、このキャストを許可しないList xlist = (List)listことは明らかです。el.

class Test {

    public static <T> void t(List<Integer> list, T el) {
        List<T> xlist = (List<T>)list; //OK
        xlist.add(el);
    }

    public static void main(String[] args) {

        List<Integer> list = new ArrayList<>();
        t(list, "a");
        t(list, "b");

        //prints [a, b] even if List type is Integer
        System.out.println(list);

    }
}
4

3 に答える 3

5

Java では、コンパイル時に常に正しくない、または常に正しいとわかっている明示的なキャストを行うと、コンパイル エラーになります。List<Integer>from からto へのキャストList<Object>は、コンパイル時に常に正しくないことがわかっているため、許可されていません。List<Integer>からto へのキャストはList<T>、コンパイル時に常に正しくないことがTわかっているわけIntegerTはありません。

于 2016-05-20T01:04:06.383 に答える
1

答えは、このキャストはInteger引数として渡すことができるという理由だけで可能elであり、その場合、そのキャストは正しいということだと思います。Integer 以外の型の他のすべてのケースでは、不正なキャストになります。しかし、ジェネリックで見られるように、正しいキャスト ( ) を与える型が少なくとも 1 つある場合Integer、コンパイラはエラーを出さず、他のすべてのケースが無効であっても警告を出します。

于 2016-05-19T20:17:08.307 に答える