ジェネリック型またはメソッド(Javaだけでなく任意の言語)を変換する必要があるコンパイラーには、原則として2つの選択肢があります。
コードの専門化。コンパイラーは、ジェネリック型またはメソッドのインスタンス化ごとに新しい表現を生成します。たとえば、コンパイラは整数のリストのコードと、文字列のリスト、日付のリスト、バッファのリストなどの追加の異なるコードを生成します。
コードシェア。コンパイラーは、ジェネリック型またはメソッドの1つの表現のみのコードを生成し、ジェネリック型またはメソッドのすべてのインスタンス化を一意の表現にマップし、必要に応じて型チェックと型変換を実行します。
Javaはコードシェア方式を使用しています。C#はコードの特殊化方法に従っていると思うので、以下のすべてのコードは、C#を使用している私によれば論理的です。
このJavaコードスニペットを想定すると:
public class Test {
public static void main(String[] args) {
Test t = new Test();
String[] newArray = t.toArray(new String[4]);
}
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
//5 as static size for the sample...
return (T[]) Arrays.copyOf(a, 5, a.getClass());
}
}
コード共有方法は、型消去が発生した後にこのコードにつながります:
public class Test {
public static void main(String[] args) {
Test t = new Test();
//Notice the cast added by the compiler here
String[] newArray = (String[])t.toArray(new String[4]);
}
@SuppressWarnings("unchecked")
public Object[] toArray(Object[] a) {
//5 as static size for the sample...
return Arrays.copyOf(a, 5, a.getClass());
}
}
だから私の質問は:
この最初のキャストを正確にする必要は何ですか?:
(T[]) Arrays.copyOf(a, 5, a.getClass());
単純に行う代わりに(型消去の前、コーディング時に):
Arrays.copyOf(a, 5, a.getClass());
このキャストはコンパイラにとって本当に必要ですか?
OK、Arrays.copyOf
戻りますObject[]
。明示的なダウンキャストなしで、より具体的なタイプから直接参照することはできません。
しかし、この場合、コンパイラはジェネリック型(戻り型!)を処理するため、努力することはできませんか?
確かに、コンパイラーがメソッドの呼び出し元の行に明示的なキャストを適用するだけでは十分ではありませんか?:
(String[])t.toArray(new String[4]);
更新しました - - - - - - - - - - - - - - - - - - - - - - - - - --------------------
@ruakhの回答に感謝します。
ここに、コンパイル時に存在するだけの明示的なキャストが関連していることを証明するサンプルがあります。
public static void main(String[] args) {
Test t = new Test();
String[] newArray = t.toArray(new String[4]);
}
public <T> T[] toArray(T[] a) {
return (T[]) Arrays.copyOf(a, 5, Object[].class);
}
キャスト先T[]
は、キャストが関係しない可能性があることをユーザーに通知する唯一の方法です。そして実際、ここではObject[]
toのダウンキャストが発生しString[]
、ClassCastException
実行時にになります。
したがって、「コンパイラがメソッドの呼び出し元の行に明示的なキャストを適用するだけでは不十分です」という点まで、答えは次のとおりです。
このキャストはコンパイルステップで自動的に作成されるため、開発者はこのキャストをマスターしません。したがって、このランタイム機能は、コンパイルを開始する前にコードの安全性を深く確認するようにユーザーに警告しません。
一言で言えば、このキャストは存在する価値があります。