2016-08-15 4 views
0
public class Array<T> { 
    private Object[] array; 
    public Array(int sz) { 
     array = new Object[sz]; 
    } 
    // .... 
    public T get(int index) { return (T)array[index]; } 
    public T[] rep() { return (T[])array; } 
} 

はなぜコンパイラは(T[])arrayが未チェックのキャストであることを言っている、と私はrep()メソッドを使用するときにClassCastExceptionがスローされますか? get()メソッド()を使用すると、この例外がスローされないのはなぜですか?ジェネリックアレイとジェネリック値の違いは何ですか?

+1

問題はジェネリックには何もありません。これは面白いことができます:[here](http://stackoverflow.com/a/13647072/5333936) – Blobonat

+0

短い答え:消去のためジェネリックタイプにキャストできません。 'Object []'の代わりに 'List 'を使ってください。 – VGR

答えて

1

get()メソッド()を使用すると、この例外がスローされないのはなぜですか?

これには2つの理由があります

  1. 何の要素があなたのプログラムにarrayに追加されなかったと仮定するとは、arraynull値のsz数で初期化されようとしている。..声明(T)array[index]ですをTにキャストしようとしています(Tは基本的にタイプ消去によってObjectに置き換えられます)。 nullはどのタイプにもキャストすることができますので、これは問題ではありません。
  2. いくつかの要素は、あなたのプログラムの中でarrayに追加されていると仮定すると、声明(T)array[index]が問題なく動作することを唯一の方法はある位置indexの要素がArrayをインスタンス化するために使用されるのと同じタイプまたはサブタイプである場合(例えばArray<Number> arr = new Array<Number>をし、しかし、arr[index]Stringを挿入してみて、あなたも同様にget方法からClassCastExceptionを取得するためにバインドされている)

なぜコンパイラは(それを言うん; arr[index]は、これは問題にならないだろう1です。 T [])配列がチェックされていないcast、そしてClass私が担当者を使用する場合CastExceptionが

)(スローされますがClassCastExceptionを取得するための唯一の方法は、Tに代表されるタイプがarrayが保持できる要素の型と同じではないということです。たとえば、何かをしてClassCastExceptionになり、次のように:ここでは

Array<Integer> a = new Array<Integer>(); 
Integer[] intArray = a.rep();//ClassCastException 

は、T[]Integer[]がそうコードをコンパイルするには問題がない表し、ただし、実行時にarrayObject[]です。 Objectの配列はIntegerの配列にダウンキャストできません。また、配列が他のクラスとは異なりJVMによって動的に作成されることを知るのに役立ちます。

これを修正する1つの方法は、ArrayArray<Object> arr = new Array<Object>としてインスタンス化することです。

1

get()には、配列内の要素の実際の実行時の型が気になるだけです。これは配列にTを入れるメソッドがあるためです。配列の実際の実行時型は関係ありません。

rep()では、配列オブジェクトの実際の実行時タイプは、T[]にキャストされているため気になります。実際のランタイムタイプObject[]の配列を作成したため、がObjectにならない限り、T[]へのキャストは常に正しくなりません。

関連する問題