Кастинг массива в Java? (ковариация и [LObject)

Мой вопрос, как точно происходит процесс приведения в Java? Предположим, у нас есть

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{

}

Я знаю, что из-за ковариации массивов, поскольку пользователь - объект, пользователь [] - также объект []. Но объяснение о создании класса ([проблема LUser и [LObject]) подрывает мое понимание ковариации. Потому что, если мы заметим [LUser и [LObject

User[] users = new User[2];
Object[] objects = (Object[]) users;
//<-- here we cast [LUser to [LObject but [LUser doesn't extends [Lobject

Так как на самом деле идет процесс кастинга? Возможно, вопросы кажутся сумасшедшими, но по логике я получил такой результат. В худшем случае я могу думать, что синтетически Java преобразует User [] в Object [], но в то время, почему нам нужно создание объектов, таких как [LObject, [LUser

1 ответ

Решение

Согласно JLS 4.10.3. Подтипирование среди типов массивов (ссылка предоставлена ​​JB Nizet):

Следующие правила определяют прямое отношение супертипа между типами массивов:

  • Если S а также T оба ссылочных типа, то S[] > 1 T[] тогда и только тогда S > 1 T,

  • Object > 1 Object[]

  • Cloneable > 1 Object[]

  • java.io.Serializable > 1 Object[]

Вышесказанное означает следующее. Конечно, вы не можете написать это, но это Java-эквивалент правил подтипов массива.

//                     Rule #2           Rule #3    Rule #4
class Object[] extends Object implements Cloneable, Serializable {
}

//                   Rule #1
class User[] extends Object[] {
}

ОБНОВИТЬ

Кроме того, JLS 10.7. Array Members говорит:

Членами типа массива являются все следующие:

  • publicfinal поле length, который содержит количество компонентов массива. length может быть положительным или нулевым.

  • public метод clone, который переопределяет метод с тем же именем в классе Object и не выбрасывает никаких проверенных исключений. Тип возвращаемого значения clone метод типа массива T[] является T[],

    Клон многомерного массива неглубокий, то есть он создает только один новый массив. Подмассивы являются общими.

  • Все члены унаследованы от класса Object; единственный метод Object это не наследуется, это его clone метод.

Это значит:

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();
    }
}
Другие вопросы по тегам