Кастинг массива в 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[]
> 1T[]
тогда и только тогдаS
> 1T
,
Object
> 1Object[]
Cloneable
> 1Object[]
java.io.Serializable
> 1Object[]
Вышесказанное означает следующее. Конечно, вы не можете написать это, но это 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 говорит:
Членами типа массива являются все следующие:
public
final
поле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();
}
}