1

次のコードを検討してください。

public class MyClass<T>{
    T data;
    public MyClass(T data){ this.data=data; }
}
public class Main{
    public static void main(String[] args){
        MyClass m= new MyClass<Integer>(3);// ok

    }
}

「生の型とは何か、それを使用すべきではない理由は?」のトピックを読みました。したがって、パラメータ化された型がある場合、生の型の定義により、コンパイル時に生の型へのMyClass<T>参照を定義できます。MyClass mさらにMyClass、指定されたパラメータ化された型に対応する生の型は、すべての特定の型の型消去前のコンパイル時MyClass<T>のスーパークラスです。この理由は正しいですか?MyClass<E> E

4

1 に答える 1

2

Angelika Langer の Generics FAQから:

生の型は、ジェネリック型のすべての具象およびすべてのワイルドカード インスタンス化のスーパータイプです。たとえば、生の型Collectionは、ジェネリック型のすべてのインスタンス化のスーパータイプCollectionです。

ジェネリック型階層

記事は次のように続きます。

変換に関しては、サブタイプからスーパータイプへの通常の参照拡大変換が許可されます。つまり、ジェネリック型のすべてのインスタンス化は、対応する生の型に変換できます。ジェネリック型と非ジェネリック型の間の互換性のために、その逆も許可されています。これは、いわゆる未チェックの変換であり、「未チェック」の警告が伴います。

コメントでさらに質問に対処するには:

生の型の場合:List lst= new ArrayList()コンパイラは何をしていますか? チェックと消去のタイプはありませんか?

ジェネリック型チェックはありません。明らかに、コンパイラArrayListは が に割り当て可能であることを確認しListます。ここでは、ジェネリック固有の処理は何も行われていません。通常、このようなコードは、ジェネリックが言語に追加される前に記述されていたはずです。下位互換性のために引き続き許可されていますが、生の型の使用についてコンパイラから警告が表示されます。

そして、なぜ正しいList lst= new ArrayList<String>()List<Integer> lst= new ArrayList()ですか?

正常にコンパイルされるという点でのみ正しいですが、ベスト プラクティスではなく、未加工の型と未チェックの変換の両方を使用すると、コンパイラの警告が発生します。

生の型は、型消去前のコンパイル時にすべてのジェネリック型のスーパータイプおよびサブタイプであることを意味しますか?

Generics FAQ で指摘されているように、生の型はそのすべてのジェネリック バリエーションのスーパータイプです。代入が両方の方法で許可される理由は、未加工の型がジェネリック型チェックを「オプトアウト」するためです。型の安全性が脅かされるため、コンパイラはこれについて警告します。

于 2013-10-04T03:34:56.973 に答える