1

ジェネリッククラスがあります

SomeClass<T>{ }

次の行を書くことができます。

SomeClass s= new SomeClass<String>();

生の型はジェネリック型のスーパータイプなので大丈夫です。しかし

SomeClass<String> s= new SomeClass();

は正しいです。なぜそれが正しいのですか?型消去は型チェック前だと思っていたのですが違います。

Hacker's GuideからJavacへ

Java コンパイラがデフォルトのコンパイル ポリシーで呼び出されると、次のパスが実行されます。

  1. parse:一連の *.java ソース ファイルを読み取り、結果のトークン シーケンスを AST ノードにマップします。
  2. enter:定義の記号を記号テーブルに入力します。
  3. 注釈の処理:要求された場合、指定されたコンパイル単位で見つかった注釈を処理します。
  4. attribute:構文ツリーの属性。このステップには、名前解決、型チェック、および定数の折りたたみが含まれます。
  5. flow:前のステップのツリーに対してデータ フロー分析を実行します。これには、割り当てと到達可能性のチェックが含まれます。
  6. desugar: AST を書き換えて、構文糖衣をいくつか取り除きます。
  7. generate:ソース ファイルまたはクラス ファイルを生成します。

Generic は構文シュガーであるため、4 パスで呼び出された型チェックの後、6 パスで型消去が呼び出されます。よくわかりません。

4

1 に答える 1

0

型パラメーターは必ず型チェックに参加します。そうしないと意味がありません (つまり、生の型に勝るものはありません)。

この情報は、暗黙的なキャストを生成するためにも必要であるため、ステップ 7 まで存続し、技術的にはデバッグ シンボルとして実行されます。ただし、実行時の型キャスト チェックに参加するのは消去だけです (明らかな後方互換性の理由から)。それにもかかわらず、ジェネリック コードを完全に静的にチェックできる場合は、非型消去言語のジェネリック プログラムと同じくらい強力にすることができます。

に代入SomeClassするSomeClass<String>と、コンパイラは生の型の使用に関する警告を表示します。この時点で、プログラムは明らかに安全ではなくなります。

于 2013-11-02T09:50:27.803 に答える