6

2 つのクラスがあるとします。

class X { }

class Y extends X { }

main 関数で配列を作成します。

Y[] yArr = new Y[3] // created Y's class objects array

X[] xArr = yArr;

xArr[0]= new X() // VALID. WHY?

それはどのようにできますか?? xArrオブジェクトを参照しているためY[]、私の理解では X オブジェクトを作成できません。

4

1 に答える 1

9

Java コンパイラではこれが可能です。これは、Java 配列が共変であるためです。つまり、次のように言えます。

Superclass[] arr = new Subclass[3];

これにより、あなたのようなコードxArr[0]= new X();をコンパイルできます。ただし、JVM は実行時にこのエラーをキャッチし、ArrayStoreException. 実行時にそれが本当に であることを認識しているため、Y[3]を格納できませんX

JLS、セクション 4.10.3は、配列型の共分散を確立します。

次のルールは、配列型間の直接のスーパータイプの関係を定義します。

  • S と T が両方とも参照型である場合、 S[] >1 T[] iff S >1 T.

  • オブジェクト >1 オブジェクト[]

  • クローン可能 >1 オブジェクト[]

  • java.io.Serializable >1 オブジェクト[]

  • P がプリミティブ型の場合、次のようになります。

    • オブジェクト >1 P[]

    • クローン可能 >1 P[]

    • java.io.Serializable >1 P[]

これは、共変でないジェネリックとは対照的です。つまり、ジェネリックは不変です。いえ

ArrayList<Superclass> list = new ArrayList<Subclass>();  // doesn't compile.
于 2013-10-28T19:40:31.190 に答える