1) 論理的な違いは何ですか?
上: Collection はジェネリック型なしで宣言できます。これはraw タイプと呼ばれます。コレクションは、あらゆる種類のコレクションを保持できます。生の型付きコレクションでは、実行時に文字列のコレクションを整数のコレクションとして使用する可能性があるため、ランタイム例外が発生し、コンパイラは通常警告をスローします。上記の例ではコレクションを入力していないため、コンパイラはこれらの実行時例外を防ぐことができません。警告の目的と実行内容がわかっている場合は、警告を無視できます。
下: ただし、Collection<String> として宣言された変数は、どのような種類のコレクションも保持できません。タイプ String のコレクションである必要があります。ストロングタイプです。コンパイラはこれをエラーとして認識します。
2) 上記のスニペットでコンパイラ エラーが発生しないのはなぜですか?
Java は厳密に型指定されているため、型の安全性が保証されます。上記のスニペットはタイプ セーフではありませんが、Java では許可されています。これはおそらく歴史的な理由によるものです。ジェネリックは Java 1.5 でのみ導入されたため、上記のスニペットがコンパイル エラーを引き起こした場合、ほとんどの Java 1.4 コードは Java 1.5 コンパイラで壊れていたでしょう。
すべてのプログラミング言語がこのように下位互換性を保って進化しているわけではありません (たとえば、PHP)。Java 1.5 の導入時には、型の安全性よりも下位互換性が重視されたようです。