My question is how is the casting process in Java exactly? suppose we have
User[] users = new User[2];//<-- here we get at runtime [LUser class
Object[] objects = (Object[]) users;//<-- here we get at runtime [LObject class
public class [LUser extends Object implements Serializable, Cloneable{
}
public class [LObject extends Object implements Serializable, Cloneable{
}
I know that because of arrays covariance as User is Object , User[] is Object[] as well. But explanation about class creation([LUser and [LObject issue) is damaging my understanding of covariance. Because if we notice [LUser and [LObject
User[] users = new User[2];
Object[] objects = (Object[]) users;
//<-- here we cast [LUser to [LObject but [LUser doesn't extends [Lobject
So how actually is going casting process? May be questions seems crazy but logically I got this result. At worst case I can think that syntatically Java cast User[] to Object[] but at that time why we need object creation like [LObject, [LUser
According to JLS 4.10.3. Subtyping among Array Types (link provided by JB Nizet):
The following rules define the direct supertype relation among array types:
If
S
andT
are both reference types, thenS[]
>1T[]
iffS
>1T
.
Object
>1Object[]
Cloneable
>1Object[]
java.io.Serializable
>1Object[]
The above means the following. Of course you can't write that, but that is the Java equivalent of the array subtyping rules.
// Rule #2 Rule #3 Rule #4
class Object[] extends Object implements Cloneable, Serializable {
}
// Rule #1
class User[] extends Object[] {
}
UPDATE
In addition, JLS 10.7. Array Members says:
The members of an array type are all of the following:
The
public
final
fieldlength
, which contains the number of components of the array.length
may be positive or zero.The
public
methodclone
, which overrides the method of the same name in classObject
and throws no checked exceptions. The return type of theclone
method of an array typeT[]
isT[]
.A clone of a multidimensional array is shallow, which is to say that it creates only a single new array. Subarrays are shared.
All the members inherited from class
Object
; the only method ofObject
that is not inherited is itsclone
method.
That then means:
class Object[] extends Object implements Cloneable, Serializable {
public final int length = /*value from array creation*/;
public Object[] clone() {
try {
return (Object[]) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e.getMessage());
}
}
}
class User[] extends Object[] {
public User[] clone() {
return (User[]) super.clone();
}
}