简体   繁体   中英

Why can you cast int[] to Object, but not to Object[]?

So this works:

int i;
Object a  = (Object) i;
int[] t;
Object b = (Object) t;
String[] s;
Object[] t = (Object[]) s;

But this does not:

int[] t;
Object[] z = (Object[]) t;

All in all I get the first part (boxing), but I find it highly unintuitive that the second part does not work. Is there a specific reason why (beside String inheriting from Object and int not inheriting from Object)?

Edit:

To refine my question, this also works:

int a = 2;
int b = 3;
int c = 4;
int d = 2;
Object[] o = new Object[] {a,b,c,d};

But then the following does not:

int[] t = (int[]) o;

Surprisingly you get the same problem with String:

String sa = "a";
String sb = "b";
String sc = "c";
String sd = "d";
Object[] so = new Object[] {sa,sb,sc,sd};
String[] st = (String[]) so;

Yields a class cast exception on the last line. Still this works:

Object[] sy = (Object[])new String[]{sa,sb,sc,sd};
String[] sz = (String[]) sy;

A int[] is an array of primitives but also an Object itself. It is not an array of Objects

There is no auto-boxing support for arrays. You need to pick the right type of array to start with and not be converting it at runtime.

Any array, including int[] is actually an Object . This is why you can cast to Object. However, int is a primitive, so it doesn't extend Object , so you cannot cast to Object[] .

As you say: String inheriting from Object and int not inheriting from Object, that's the reason. int, boolean, double... are primitive types and they don't extend from Object. You should use Integer instead of int.

Integer[] t;
Object[] z = (Object[]) t;

An object is a class instance or an array.

It is stated in The JLS section 4.3.1 .

Now, int[] is an array, which is an Object.

String[] s; 

and

int[]

differ in following way:

Former can point to an array of String objects, but latter can point to an array of primitive int .

I just found the answer I was looking for myself. The reason why you cannot cast int[] to Object[] is not because int is a primitive and does not extend Object , but because int[] itself does not extend Object[] . In code:

int[] t = new int[0];
Object ot = t;
System.out.println(ot instanceof Object[]);
// --> prints 'false'
String[] s = new String[0];
Object os = s;
System.out.println(os instanceof Object[]);
// --> prints 'true'

Edit: the boxing is necessary because Eclipse knows that int[] and Object[] are incompatible.

Edit II: Btw this if(obj instanceof Object[]) allows to check wether a boxed array is an array of a primitive type.

According to Java Spec 4.10.3 Subtyping among Array Types :

  • If S and T are both reference types, then S[] > 1 T[] iff S > 1 T.
  • Object > 1 Object[]

  • If P is a primitive type, then Object > 1 P[]

S > 1 T means that T is a direct subtype of S

It basically means, that int[] and Integer[] are in different branches of type hierarchy in Java and can't be cast one to another.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM