2016-09-03 6 views
24

私が知っているように、Javaのジェネリックスの主な目的の1つは、コンパイル時の型の安全性を提供することです。コンパイルされると、コードは問題なく実行されます。コンパイルエラーなしで文字列がリストに割り当てられる

次に、次のコードがコンパイルされているのはなぜですか?

public static void main(String[] args) { 
    String s = getList(); 
} 

private static <T extends List> T getList() { 
    return (T)new ArrayList(); 
} 

コンパイルが正常です。タイプセーフなコンパイルはどこですか? getList()メソッドは、Stringクラスとは何も共通しません。

+1

いいえ、非生の型を使用している場合でもコンパイルされます。 –

+0

@MarkusFischer、 私はそれについても考えましたが、コンパイラはStringが最終クラスであり、サブクラスを持つことができないことを認識しています – Andrew

+1

@ MarkusFischer、このコメントを答えに変換する必要があります。私はそれがまさにここで観察される問題だと思う。あなたが言ったように、コンパイラは文字列をfinalと見なさないので、 'MyClass extends String implements List'はコンパイル時に可能です。 – Zabuza

答えて

13

これはタイプイレーズの問題ではありませんが、ほぼ反対です。実際のタイプはコンパイル時ではなく、実行時に問題になります。これがコンパイルされる理由は、Listがインタフェースです。コンパイラに関しては、Stringというサブクラスが実際にそのインタフェースを実装する可能性があるため、実際のオブジェクトがStringList)の有効な実行時状況が存在する可能性があります。コンパイラはStringがfinalであるとは考えていないため、Listを実装してStringクラスを実際に作成することは不可能です。

コンパイル時にファイナルが考慮されない理由について、ボヘミアンの質問に対するコメントは良い説明を与えます。

+0

少なくともコンパイラの警告はありませんか?私はjavac自体をチェックしていませんが、私のIDEはチェックされていないキャストと生の型について何も警告しません。生の型がなく、警告がないところで型が明らかに正しくない場合の例を取り上げることができます。 – RudolphEst

+0

私はコンパイラの警告がうまくいくことに同意し、この状況には意味をなさないでしょう。私はjavacやEclipseのどちらも見ません。このことは、コンパイラが調査したエッジケースの数になります。明らかに、このコンスタレーションをチェックしないという決定が下されました。 –

関連する問題