27

最後に、ジェネリックを少し試してみました。私はこのコードを思いつきました:

public class Test {

    static <T> void f(T x) {
        x = (T) (Integer) 1234;
        System.out.println(x);
    }

    public static void main(String[] args) {
        f("a");
        f(1);
        f('a');
        f(1.5);
        f(new LinkedList<String>());
        f(new HashMap<String, String>());
    }
}

これを実行したところ、次の出力が得られました。

1234
1234
1234
1234
1234
1234

例外なく!それはどのように可能ですか?

4

2 に答える 2

37

これは型の消去が原因です(これについては多くのことが書かれていますが、この用語についてはググってください)。バイト コードにコンパイルfすると、メソッドは次のようになります。

static void f(Object x) {
    x = (Object) (Integer) 1234;
    System.out.println(x);
}

したがって、オブジェクトSystem.out.printlnのメソッドを呼び出すだけです-そしてあなたの場合は.toStringxInteger.toString()

于 2013-08-07T11:55:31.687 に答える
4

型消去のため。オラクルのドキュメントから:

ジェネリックは、コンパイル時のより厳密な型チェックを提供し、ジェネリック プログラミングをサポートするために、Java 言語に導入されました。ジェネリックスを実装するために、Java コンパイラは型消去を以下に適用します。

  • ジェネリック型のすべての型パラメーターをそれらの境界またはオブジェクト (型パラメーターが無制限の場合) に置き換えます。したがって、生成されたバイトコードには、通常のクラス、インターフェース、およびメソッドのみが含まれます。

  • 型の安全性を維持するために、必要に応じて型キャストを挿入します。

  • 拡張されたジェネリック型でポリモーフィズムを保持するブリッジ メソッドを生成します。

型の消去により、パラメーター化された型に対して新しいクラスが作成されないことが保証されます。したがって、ジェネリックはランタイム オーバーヘッドを発生させません。

于 2013-08-07T11:59:23.830 に答える