ホームページ >Java >&#&チュートリアル >Java ではなぜジェネリック型パラメータを「スーパー」でバインドできないのでしょうか?
Java でジェネリックを扱う場合、多くの場合、特定の型との互換性を確保するために型パラメーターを境界付ける必要があります。 「super」キーワードを使用すると、型パラメーターが指定された型のスーパークラスまたはスーパーインターフェイスである必要があることを指定できます。ただし、この使用法はワイルドカードでのみ許可され、型パラメータでは許可されません。
Collection インターフェイスでは、toArray メソッドは次のように宣言されます。
<T> T[] toArray(T[] a);
このメソッドを使用すると、コレクションを変換できます。型「T」の要素を同じ型の要素の配列に変換します。ただし、次のようにメソッドを記述することはできません:
<T> <S super T> S[] toArray(S[] a);
その理由は、ジェネリックスの 'super' キーワードが型パラメーターではなくワイルドカードをバインドするために使用されるためです。上記の例では、「super」を使用して型パラメータ 'S' を 'T' のスーパークラスまたはスーパーインターフェイスにバインドしようとしています。この使用法は、型安全性の問題につながる可能性があるため許可されません。
たとえば、次のコードを考えてみましょう。
List<Integer> integerList = new ArrayList<>(); Integer[] integerArray = new Integer[5]; Number[] numberArray = new Number[5]; Object[] objectArray = new Object[5]; // hypothetical method integerList.toArray(super T numberArray)
提案された構文によれば、上記のコードでは、次の型割り当て:
integerList.toArray(super T integerArray) // compiles fine! integerList.toArray(super T numberArray) // compiles fine! integerList.toArray(super T objectArray) // compiles fine!
ただし、'String' は 'Integer' のスーパークラスではないため、次のコードはコンパイルできません:
integerList.toArray(super T stringArray) // should not compile
ただし、繰り返しになりますが、'Object ' が 'Integer' と 'String' の両方のスーパークラスである場合、次のコードは実行時に 'ArrayStoreException' をスローする場合でもコンパイルされます:
integerList.toArray(super T stringArray) // compiles fine!
この動作は、次のような問題を引き起こす可能性があるため望ましくありません。入力の安全性違反。これを防ぐために、Java ではバインドされた型パラメータに「super」を使用することを許可していません。代わりに、'super' を使用してワイルドカードをバインドすることのみが可能です。
たとえば、ワイルドカードを使用して toArray メソッドを次のように書き換えることができます。
<T> T[] toArray(T[] a);
このメソッドを使用すると、コードを作成できます。これはタイプセーフでありながら柔軟性があります。たとえば、次のコードはコンパイルされ、実行時に 'ArrayStoreException' をスローしません:
List<Integer> integerList = new ArrayList<>(); Integer[] integerArray = new Integer[5]; Number[] numberArray = new Number[5]; Object[] objectArray = new Object[5]; integerList.toArray(objectArray);
以上がJava ではなぜジェネリック型パラメータを「スーパー」でバインドできないのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。