Search code examples
javaarrayscovariance

Casting array process in Java? (covariance and [LObject)


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


Solution

  • 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 and T are both reference types, then S[] >1 T[] iff S >1 T.

    • Object >1 Object[]

    • Cloneable >1 Object[]

    • java.io.Serializable >1 Object[]

    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 field length, which contains the number of components of the array. length may be positive or zero.

    • The public method clone, which overrides the method of the same name in class Object and throws no checked exceptions. The return type of the clone method of an array type T[] is T[].

      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 of Object that is not inherited is its clone 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();
        }
    }