9

JLS 7、5.1.6ナローイング参照変換によると

• SC と TC が参照型であり、SC から TC への縮小参照変換がある場合、任意の配列型 SC[] から任意の配列型 TC[] へ。

Object[] objArr = {"a","b","c"};
String[] strArr = (String[])objArr; // ClassCastException

上記の例では、objArr と strArr の両方が参照型であり、Object から String への狭い参照変換があります。

Object obj = "a";
String str = (String)obj;

ただし、次のコードは正常に機能します。

Object[] objArr = (Object[])java.lang.reflect.Array.newInstance(String.class, 3);
String[] strArr = (String[])objArr;

Javaがキャストを行うために使用するルールを尋ねたいと思います。私が知る限り、2 つの例の違いは、最初の例では、objArr が Object 型のコンポーネントを持つ Object 配列であることです。2 つ目は、String 型のコンポーネントを持つ Object 配列です。

Arrays.copyOf または他のライブラリを使用してこれを行う方法を示していないことに注意してください。

4

3 に答える 3

7
Object[] objArr = {"a","b","c"};
String[] strArr = (String[])objArr;

それで、問題はs ではなくs の{"a","b","c"}配列です。ObjectString

それは次のように何かをするようなものです -

Object obj = new Object();
String str = (String) obj; //ClassCastException

以下も例外ではありません -

Object[] objArr = new String[] {"a","b","c"}; //Which is the case when you are using reflection
String[] strArr = (String[])objArr; //No exception

そして、それは次のように何かをするようなものです -

Object obj = new String();
String str = (String) obj;
于 2012-10-02T15:20:48.103 に答える
1

最初の例の「objArr」は Object[] 型です。2 番目の例の「objArr」は String[] 型です。

String は Object を拡張しますが (String は Object の型です)、String[] は Object[] を拡張しません (String-Array Object は Object-Array の型ではありません)。

最初の例で String を Object[] (Object-Array) オブジェクトに入れても、String[] (String-array) にはなりません。

Object[] objArr = {"a","b","c"};
System.out.println(objArr instanceof Object[]);//true
System.out.println(objArr instanceof String[]);//false

String[] objArr2 = {"a", "b", "c"};
System.out.println(objArr2 instanceof Object[]);//false
System.out.println(objArr2 instanceof String[]);//true

== 共分散について

私が完全に把握しているわけではありませんが、ここから得られることは次のとおりです。

Java 配列は共変ですが、ジェネリックはそうではありません。これが機能することを意味します:

Object[] o = new String[3];

これはしません:

//ArrayList<Object> o = new ArrayList<String>(); //compile time error

また、これは機能します:

function1(new String[2]);
static void function1(Object[] o) {

    }

これはしません:

//function2(new ArrayList<String>()); //compile time error
 static void function2(ArrayList<Object> o) {

    }

ジェネリックがそのように制限されたのには十分な理由がありますが、それはこの議論の要点ではありません。

ただし、これは実際には共分散に関する議論ではなく、一部のクラスが Java でどのように実装されているかについての議論であると私は信じています。タイプ String[] のオブジェクトは、タイプ Object[] のオブジェクトでもあります (それがもたらすすべての悪いものを伴います)。したがって、次のように記述できるのは正常です。

Object[] o = new String[3];

ただし、配列の共分散のために、String[] を Object[] として扱うことができ、Object[] にはどのような種類でも配置できるため、具体的には String をオブジェクト配列に配置できます。IEあなたはこれを持つことができます:

Object[] o = //whatever kind of array;
o[0] = //whatever kind of instance;

ただし、これは、最後の例の o が Object[] 型であるという事実を変更しないため、それを String[] にキャストすることはできません。

于 2012-10-02T15:24:53.073 に答える
0
Object[] objArr = {"a","b","c"};
String[] strArr = (String[])objArr; // ClassCastException

上記の例では、objArr と strArr の両方が参照型であり、Object から String への狭い参照変換があります。

配列参照からObject 配列参照にキャストしていることに注意してください。したがって、個々の参照を参照にキャストしていないため、縮小は適用されません。String ObjectString

于 2012-10-02T15:26:08.160 に答える