生の型とジェネリック メソッドの組み合わせ: 予期せぬ結果
生の型とジェネリック メソッドを扱う場合、予期しない動作が発生する可能性があります。次のコード スニペットを考えてみましょう:
ArrayList<String> a = new ArrayList<String>(); String[] s = a.toArray(new String[0]);
このコードは、JDK 1.6 と 1.7 の両方で正常にコンパイルされます。ただし、ArrayList 参照を raw 型に変更すると、コンパイラ エラーが発生します:
ArrayList a = new ArrayList(); String[] s = a.toArray(new String[0]); // Error: String[] expected, Object[] found
驚くべきことに、コンパイラは、引数として String[] を受け取ったにもかかわらず、ジェネリック メソッド toArray を Object[] を返すものとして解釈します。これは、メソッドがその型パラメータに準拠することを期待しているため、直観に反しています。
動作を理解する
JLS 4.8 は、この動作を明らかにします。
「スーパークラスまたはスーパーインターフェイスから継承されていない生の型 C のコンストラクター、インスタンス メソッド、または非静的フィールド M の型は、対応するジェネリック宣言内の型の消去に対応する生の型です。 "
簡単に言えば、生の型を扱うとき、コンパイラはメソッドまたはフィールドに関連付けられた型パラメータを無視します。したがって、生の型 ArrayList の toArray メソッドの型は、型パラメーター T に関係なく、Object[] です。
この動作は、ジェネリック メソッドを超えて拡張されます。クラスの他の部分でジェネリックを使用する場合でも、それを生の型として参照すると、そのインスタンス内でのジェネリックの使用が事実上無効になります。たとえば、次のコードは未チェックの警告を生成します:
public class MyContainer <T> { public List<String> strings() { return Arrays.asList("a", "b"); } } MyContainer container = new MyContainer<>(); List<String> strings = container.strings(); // Unchecked warning
結論
生の型とジェネリック メソッドを扱う場合、生の型とジェネリック メソッドを使用することを理解することが重要です。 type は、その特定のインスタンスに対するジェネリックスの使用を無効にします。生の型は混乱を招く予期しない動作につながる可能性があるため、慎重に使用してください。
以上がJava のジェネリック メソッドで生の型を使用すると、予期しない型の動作が発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。