2013-07-12 15 views
5

私の理解では、Javaに生の型と型の消去があるのは、ジェネリックが導入されたときに、既存のコードを壊すことなくジェネリックにすることのできなかった標準APIがあったからです。生の型/型の消去を必要とせずにジェネリックスに対応できないJava(.NETではありません)はなぜですか?

ジェネリックスも.NETのいくつかの時点で導入されましたが、この機能は生の型や型の削除に依存しない方法で実装されています(そうであれば、ユーザーにはわかりません)。したがって、既存のAPIは変更されず(System.Collections名前空間のコードなど)、新しい汎用API(System.Collections.Generic名前空間のコードなど)が導入されました。

.NETのジェネリックスとは異なり、Javaのジェネリックはどのように生のタイプ/タイプの消去が必要ですか?

答えて

8

.Netは、バイトコード言語、仮想マシン、およびJITterを変更してジェネリック型を認識するようにジェネリックを導入しました。
これは約2年かかった膨大な量の作業でした。

Javaは、わずかなランタイムの変更(新しいメタデータとリフレクションAPI)だけで、コンパイル時の機能として純粋に導入されました。
これははるかに簡単な作業で、以前のランタイムとの下位互換性を維持していましたが、作業するのがはるかに面倒です。

+3

さらに、.Netは既存のコンテナを異なる名前空間の汎用バージョンに置き換えました。それらを使用したいコードは、一度に移植する必要があります。 Javaの方法では、単に既存のコンテナを汎用にすることができました。したがって、ビット単位での移植は、時折キャストと警告の抑制を意味します。 –

+0

@SebastianRedl:基本的に、コンパイル時のみの機能であるジェネリックの拡張です。 – SLaks

+0

.NETはバイトコード言語を変更しましたが、汎用オブジェクトがその型を知るためにJavaが必ずしもそうする必要はなかったと思います。私は、すべての汎用オブジェクトインスタンスがインスタンス化された型の組み合わせを示す1つ以上のコンパイラ生成フィールドを含むことができ、適切なときにこのようなフィールドを検証するコードをコンパイラが生成することができると考えていました。 'ArrayList 'が 'ArrayList'以外の型であると実装された場合、もっと大きな問題があると思います... – supercat

3

Sunは、Javaソフトウェアの大きな拠点だったため、後方互換性を保証することが特に賢明でした。これを行うために、彼らはJVMの変更の最小限が最善であると感じました。後見では、JVMがジェネリックを本当に理解しておらず、多くの冗長クラスチェックを最適化できないという意味で、長期的には最良の決定ではないようです。

Oracleは、JVMを変更することにあまり躊躇しておらず、より深刻なバグやパブリックなバグに苦しんでいます。セキュリティと関係があります。それでも、オラクルはJVMにJavaを使用しない命令を1つだけ追加していますが、Sunはこれを追加していないため、実際には相対的なものです。 ;)

マイクロソフトは、一方で、C#のコードベースが小さく、メジャーバージョン間の大幅な変更、さらには大幅な変更にも慣れています。これは短期的にはより多くの痛みを意味しますが、長期的にはより良い選択となります。あなたは歴史的な理由が残っているため、問題が少なくなっています。

簡潔には違いは技術的ではなく、より政治的で歴史的です。

+1

違いは**非常に**技術的です。 – SLaks

関連する問題