2016-09-07 4 views
4

まず、javaは厳密な型システムを持っているので、プログラムはコンパイル時に型の正しさがチェックされ、プログラムのバイトコードは実行前にバイトコードベリファイアにロードされます。Javaにおけるジェネリックスとサブタイプの問題

ジェネリック医薬品の導入は、Javaの型システムのpotencialsを広げていますが、原因のjavaに多くの問題は、上記の例では、このような発生のサブタイプがありますが:私たちは、Stringクラスであることを使用して上記の例では

String [] a ={"Hello"}; 
     Object [] b= a; 
     b[0]= false; 
     String s=a[0]; 

     System.out.println(s); 

Objectのサブクラスです。 私の質問は、上記のプログラムに関する警告がコンパイラによって生成されない理由です。実行すると(もちろん)例外がスローされます。 また、上記のプログラムがJava実装で持つことができる問題/結果(私には明らかな問題がありますか?)。

+0

まずBrachaのGenerics tutorialを読んでください。 –

+1

質問自体については、それはダップです:http://stackoverflow.com/questions/18666710/why-are-arrays-covariant-but-generics-are-invariant –

+0

もしあなたが高レベルのアーチ討論、プログラマー.seはこの種の質問にもっと適しているようです。 –

答えて

2

Javaの配列は共変型です。 String[]は、Object[]を予期しているものに渡すことができます。これは、コンパイラがString配列にブール値を固定するのを止めない理由です。

共分散を提供するだけでなく、実行時の保護を提供するために、Javaエンジニアは配列を設計してコンパイル時にタグを追加し、その型で配列をスタンプします。ブール値をコンパイル時に追加することはできますが、String[]の型は、実行時にブール値を追加するのをやめます。これはコードを実行したときにおそらく発生したArrayStoreExceptionをトリガーします。

これは、共変配列を持つことと、配列に間違ったものを追加することの間にあるJavaのトレードオフです。これは、Scalaのようないくつかの言語が共変配列を持たないことを選択した理由です。

ジェネリックアレイを作成することは可能ですが、単純ではなく、いくつかのタイプの危険性があります。そのため、特定のユースケースに対応しています.Josh BlochのEffective Javaではこれについて説明しています。

コンパイル時に問題を捕まえることができるので、配列全体の汎用リストを使用する方がよいでしょう。

+0

@ Nio、これは助けてくれてありがとう、なぜそれがコンパイルされているのかがはっきりしています。私はその多くの経験をJavaで持っていないので、これはjava実装のさらなる問題につながる?? (それにはさらなる影響がありますか?幅広い答えを求めることはありません)。 – coder

+1

@コーダー、私はあなたの質問を得るのは100%ではありませんが、私があなたを正しく理解していれば、それ以上の心配はありません。私はあなたがJavaでそれほど経験がなければ、配列を避けて、コンパイラがリストに間違ったものを追加するのを止めるので、ジェネリックListを使用すると言うでしょう。本当に配列を使用したい場合は、それらの配列を保護することに非常に注意する必要があります。メソッドからそれらを返さないと、ランタイムまで表示されないかもしれない間違ったものを誰かが追加する危険性があります。 – Nio

+0

ニオ、おかげであなたの答えはたくさん助けられました! – coder

関連する問題