2012-03-24 12 views
0

シナリオA.java -----------消去後--------> M.classJavaの:ジェネリック消去が

シナリオのしくみB.java-- ---------消去後--------- M.class

なぜAは違法で、Bは消去後もほぼ同じMであるため、Bは合法です。消去前

シナリオA:

class ArrayList<V> { 
private V[] backingArray; 
     public ArrayList() { 
      backingArray = new V[DEFAULT_SIZE]; // illegal 
      } 
} 

消去後シナリオA:

class ArrayList<V> { 
    private Object[] backingArray; 
     public ArrayList() { 
     backingArray = new Object[DEFAULT_SIZE]; // this is not useful 
    } 
} 

実際にオブジェクトが[DEFAULT_SIZE】消去前有用〜 シナリオBである:

class ArrayList<V> { 
    private V[] backingArray; 
    public ArrayList() { 
    backingArray = (V[]) new Object[DEFAULT_SIZE]; 
    } 
} 

消去後のシナリオB:

class ArrayList<V> { 
    private Object[] backingArray; 
    public ArrayList() { 
    backingArray = (Object[]) new Object[DEFAULT_SIZE]; 
    } 
} 

答えて

6

シナリオAが不正である理由は、Javaの共変配列がでなく、消去で実装されたであるためです。この:fooは配列インスタンスを参照するためを知っていること

Object[] foo = new String[4]; 
foo[0] = new Object(); 

は、コンパイル時の型Object[]を持っている、それはそれは変数foo経由で呼ばれますにもかかわらず(String[]だ、実行時にArrayStoreExceptionが発生します)。したがって、実行時には作成する配列インスタンスの型がわからないため、

は無効です。

+0

あなたが消去後のコードシナリオAを意味するのは間違っていますか? 'backingArray = new V [DEFAULT_SIZE];'は 'backingArray = new Object [DEFAULT_SIZE];' – iamx7777777

+0

にはならないので、コンパイルエラーが発生します。したがって、新しいオブジェクト[DEFAULT_SIZE]ではなく、何かになることはありません。これは 'new V()'が 'new Object()'になれないのと同じです。 – ruakh

+0

ありがとうございました。これについての別の質問ですが、コンパイラがシナリオAを前にシナリオAにコンパイルするとうまくいくと思いますか?コンパイラがV-> Objectを変換するだけであれば違いはないと思います。 – iamx7777777

関連する問題