Почему вы можете привести int[] к Object, но не к Object[]?

Итак, это работает:

int i;
Object a  = (Object) i;
int[] t;
Object b = (Object) t;
String[] s;
Object[] t = (Object[]) s;

Но это не так:

int[] t;
Object[] z = (Object[]) t;

В целом я понимаю первую часть (бокс), но мне кажется крайне неинтуитивным, что вторая часть не работает. Есть ли конкретная причина, по которой (кроме того, что String наследуется от объекта, а int не наследуется от объекта)?

Редактировать:

Чтобы уточнить мой вопрос, это также работает:

int a = 2;
int b = 3;
int c = 4;
int d = 2;
Object[] o = new Object[] {a,b,c,d};

Но тогда нет следующего:

int[] t = (int[]) o;

Удивительно, но у вас возникает та же проблема со строкой:

String sa = "a";
String sb = "b";
String sc = "c";
String sd = "d";
Object[] so = new Object[] {sa,sb,sc,sd};
String[] st = (String[]) so;

Выдает исключение приведения класса в последней строке. Тем не менее это работает:

Object[] sy = (Object[])new String[]{sa,sb,sc,sd};
String[] sz = (String[]) sy;

person Lucas Hoepner    schedule 31.10.2012    source источник
comment
int ни от кого не наследует.   -  person    schedule 31.10.2012
comment
Массивы — это объекты; массив целых чисел является массивом и, следовательно, объектом. целые числа не являются объектами, поэтому массив целых чисел не является массивом объектов.   -  person ignis    schedule 31.10.2012


Ответы (6)


int[] — это массив примитивов, но также и сам объект. Это не массив объектов

Для массивов нет поддержки автоматической упаковки. Вам нужно выбрать правильный тип массива для начала, а не преобразовывать его во время выполнения.

person Peter Lawrey    schedule 31.10.2012

Любой массив, включая int[], на самом деле является Object. Вот почему вы можете приводить к Object. Однако int является примитивом, поэтому он не расширяет Object, поэтому вы не можете привести его к Object[].

person Dan D.    schedule 31.10.2012

Как вы говорите: String наследуется от Object, а int не наследуется от Object, вот в чем причина. int, boolean, double... являются примитивными типами и не расширяются от Object. Вы должны использовать Integer вместо int.

Integer[] t;
Object[] z = (Object[]) t;
person Anh Tuan    schedule 31.10.2012


Я только что нашел ответ, который искал для себя. Причина, по которой вы не можете привести int[] к Object[], не в том, что int является примитивом и не расширяет Object, а в том, что int[] само по себе не расширяет Object[]. В коде:

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'

Редактировать: бокс необходим, потому что Eclipse знает, что int[] и Object[] несовместимы.

Редактировать II: Кстати, этот if(obj instanceof Object[]) позволяет проверить, является ли массив в штучной упаковке массивом примитивного типа.

person Lucas Hoepner    schedule 31.10.2012
comment
Re: Редактировать II: вам нужно убедиться, что obj также является массивом, прежде чем это утверждение будет истинным! Но в любом случае я бы предложил следующий способ для любопытства будущих читателей вашего кода (включая вас): obj.getClass().isArray() && obj.getClass().getComponentType().isPrimitive(). Если вам нужно взломать, взломайте хорошо :) - person TWiStErRob; 05.07.2014

В соответствии со спецификацией Java 4.10.3 Подтип среди типов массивов:

  • Если S и T оба являются ссылочными типами, то S[] ›1 T[] тогда и только тогда, когда S ›1 T.

  • Объект ›1 Объект[]

  • Если P является примитивным типом, то Object ›1 P[]

S ›1 T означает, что T является прямым подтипом S

В основном это означает, что int[] и Integer[] находятся в разных ветвях иерархии типов в Java и не могут быть приведены друг к другу.

person kolobok    schedule 26.04.2017