1

今日、このコードがコンパイルされたとき、私は驚きました:

class GenericClass<T> {
    public void emptyMethod(T instance) {
        // ..
    }

    public void print(T instance) {
        System.out.println(instance);
    }
}

public class Main {

    public static void main(String[] args) {
        GenericClass first = new GenericClass();
        System.out.println("Wow");
        first.emptyMethod(10);
        first.print(16);
    }

}

コンパイラは警告を発します (タイプ セーフティ: メソッド emptyMethod(Object) は生の型 GenericList に属します。ジェネリック型 GenericList への参照はパラメータ化する必要があります) が、コンパイラ エラーは発生せず、「正常に」実行されます (少なくとも指定された印刷方法)。私が理解しているように、コンパイラはオブジェクトを型引数として使用していますが、直感に反していると思います。なぜコンパイラはそのようなことをするのでしょうか? 型パラメーターを指定する必要がないのはなぜですか?

4

2 に答える 2

7

基本的に、生のクラスを使用しています。

ジェネリックが Java に最初に導入されたときのことを思い出してください。すでに などを使用してListいるArrayListコードが大量にありました。そのコードをすべて壊すのを避けながら、既存のクラスを再利用するために、生の型が導入されました。基本的にはジェネリックを使用しています。ではないかのように入力します。

ご覧のとおり、警告が表示されるため、回避する価値がありますが、それが許可されている主な理由です。

以下を含む詳細については、JLS のセクション 4.8を参照してください。

生の型は、ワイルドカードと密接に関連しています。どちらも実存型に基づいています。生の型は、従来のコードとのやり取りに対応するために、型規則が意図的に不適切なワイルドカードと考えることができます。歴史的に、生の型はワイルドカードよりも優先されました。それらは GJ で最初に導入され、オブジェクトに関する ACM 会議の議事録の Gilad Bracha、Martin Odersky、David Stoutamire、および Philip Wadler による論文 Making the future safe for the past: Adding Genericity to the Java Programming Language で説明されています。 Oriented Programming, Systems, Languages and Applications (OOPSLA 98)、1998 年 10 月。

于 2013-02-07T19:57:44.877 に答える
2

ジェネリックが Java でどのように実装されているかを知る必要があります。それらは完璧には程遠いです。実行時にはすべてがオブジェクトであることを覚えておく必要があります。実行時に型はありません。

必要な場所でセキュリティを強化するためにジェネリックが追加されましたが、使用したくない場合は、警告を無視してパラメーター化されていないインスタンスを使用できます。

ただし、Java コンパイラで型の安全性を確保したい場合は、ジェネリック クラスのインスタンスをパラメータ化します。たとえば、GenericClass を作成すると、コンパイラはそれを整数パラメーターで使用することを許可しません (first.emptyMethod(10) はコンパイルされません)。ただし、明示的な型キャストを行う場合は、整数パラメーターで機能させることができます。

そのため、セキュリティを強化するための良い方法と考えてください。これは、ルールに従っている場合にのみ機能します。

于 2013-02-07T19:58:33.510 に答える