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

6

3

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;
Mainland answered 31/10, 2012 at 9:26 Comment(2)
int doesn't inherit from anybody.Misguide
Arrays are objects; an array of ints is an array, and thus an object. ints are not objects, so an array of ints is not an array of objects.Ent
M
0

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.

Mainland answered 31/10, 2012 at 12:25 Comment(1)
Re: Edit II: you'd need to make sure that obj is an array as well before that statement is true! But by any means I'd suggest the following way for curiosity to future readers of your code (including you): obj.getClass().isArray() && obj.getClass().getComponentType().isPrimitive(). If you need to "hack", hack well :)Sokil
T
5

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.

Tabbi answered 31/10, 2012 at 9:28 Comment(0)
T
2

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[].

Teage answered 31/10, 2012 at 9:28 Comment(0)
C
1

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;
Centner answered 31/10, 2012 at 9:31 Comment(0)
J
1

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.

Jovian answered 31/10, 2012 at 9:36 Comment(1)
Correct link is docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.3.1Solubility
M
0

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.

Mainland answered 31/10, 2012 at 12:25 Comment(1)
Re: Edit II: you'd need to make sure that obj is an array as well before that statement is true! But by any means I'd suggest the following way for curiosity to future readers of your code (including you): obj.getClass().isArray() && obj.getClass().getComponentType().isPrimitive(). If you need to "hack", hack well :)Sokil
S
0

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.

Solubility answered 26/4, 2017 at 12:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.