14

次のコードは私を混乱させます:

Object[] arr1 = new String[]{"a", "b", "c"};
Object[] arr2 = {"a", "b", "c"};

String[] a = (String[]) arr1; // ok
String[] b = (String[]) arr2; // ClassCastException

System.out.println(arr1.getClass().getName()); // [Ljava.lang.String;
System.out.println(arr2.getClass().getName()); // [Ljava.lang.Object;

2 つの初期化が互いに異なる理由を理解しようとしています。1 つ目は post 宣言で、2 つ目はショートカットです。2つは両方とも次のように宣言されていますObject[]

私の素朴な理解は次のとおりです。

Object[] arr2 = {"a", "b", "c"}; // is a syntax sugar of
Object[] arr2 = new Object[] {"a", "b", "c"};

したがって、 の実行時の型はarr2Object[]変換できませんString[]

しかし、Java Array は共変であるため、ここで 事態は奇妙String[]Object[]なりarr2ます。String[]Object[]String[]arr2

これに関する説明は高く評価されています。

4

4 に答える 4

6

arr2は であるためObject[]、書くことを妨げるものは何もありません

arr2[0] = new Object();

とにかくキャストが意味をなさない場合、キャストの直前に。

初期化子の構文が機能する方法のため、次の点にも注意してください。

Object x = {"a", "b"}; // error: illegal initializer for Object
Object[] a = {"a", "b"}; //a has class [Ljava.lang.Object; 
String[] b = {"a", "b"};  //b has class [Ljava.lang.String; 

コンパイラは、宣言に基づいて、配列を にするか にするかを決定Object[]します。String[]

于 2015-07-29T12:46:10.190 に答える
5

arr2 はまさに String[] です

いいえ、そうではありませんObject[]-あなたが言ったように、それはです-あなたの行は次と同等です:

Object[] arr2 = new Object[] {"a", "b", "c"};

現時点ではすべて文字列参照である要素がありますが、次のように書くこともできObject[]ます

arr2[0] = new Object(); // Fine, because arr2 is an Object[]

で同じことをするとarr1、例外が発生します。

arr1[0] = new Object(); // Fine at compile time, will throw an exception

もちろん、以下を使用して、オブジェクトの実際の実行時のタイプを確認できます。getClass

System.out.println(arr2.getClass());
于 2015-07-29T12:46:26.070 に答える