В приведенном ниже коде EX1 и EX 2 подтверждают однородную теорию, но в EX3 он содержит значения нескольких типов. Итак, как мы можем сказать, что массивы однородны? Какая точная теория стоит за этим?
public class Test {
public static void main(String[] args) {
// Ex 1
int [] intArr = new int[5];
intArr[0] = 1;
intArr[1] = 2;
// Ex 2
int [] intArr2 = new int[5];
intArr2[0] = 1;
intArr2[1] = "ss";
// Ex 3
Object [] objArr = new Object[5];
objArr[0] = 1;
objArr[1] = "ss";
objArr[3] = new Object();
}
}
@TimBiegeleisen Я думаю, что часть OP указывает на то, что массивы однородны, OP должен пометить Ex 2 как вызывающий ошибку компиляции.
@xtratic Да, после просмотра комментария Random Guy я понял вопрос.
@Sandun Perera В примере 3 objArr[0] содержит Integer, который представляет собой Object, упакованный из int; objArr[1] содержит String, который является Object; и objArr[3] содержит Object, который явно является Object. Итак, у вас есть полный массив Objects.
@ Тим Бигелейзен: Ага, Ex1 и EX3 работают нормально. EX2 имеет ошибку компиляции.




Здесь есть две концепции: наследование и автобокс.
Наследование - Строка наследуется от объекта и, следовательно, является объектом. Это означает, что String автоматически получает все методы и свойства, определенные в классе Object, во время компиляции. Это объект плюс дополнительные вещи, специфичные для String. Однако Java может рассматривать его как объект, потому что это объект. Когда он добавляется в массив, он добавляется как объект, а не как строка. Это потому, что массив определяется как массив объектов.
char a = "ss".charAt(1); // Legal as charAt(..) is a method in the String class
Object [] objArr = new Object[5];
objArr[1] = "ss";
objArr[1].charAt(1); // Not legal because charAt(..) method is not defined for Object
См. Учебник Oracle.
Авто-бокс - Java выполняет ярлык, известный как автоматическая упаковка, для автоматического преобразования примитивов в специальный набор классов-оболочек, все из которых наследуются от Object. Следовательно, из-за автоматической упаковки и наследования присвоение номера объекту также преобразует это число в объект.
Следовательно, все, что добавлено в массив, было добавлено как объект. Верно, что объекты в массиве могут быть классами, унаследованными от Object. Однако, что касается массива, они относятся к типу Object. Даже в этом случае, если бы вы вытащили его из массива и преобразовали как целое число, вы могли бы это сделать. Он по-прежнему несет с собой целочисленную информацию, но эта информация недоступна без приведения. С точки зрения массива это всего лишь объект.
См. Учебник Oracle.
Спасибо, я понял вашу точку зрения. Вы имели в виду, что число 1 (int) преобразуется в Integer (класс Wrapper) 1 и снова преобразуется в Object при добавлении в массив?
Почти. Он преобразует 1 в класс-оболочку Integer. Однако, когда он добавляет его в массив, я бы не сказал, что он его преобразует. Здесь это немного запутывает. Он добавляет его в массив как объект. Однако, если бы вы вытащили его из массива и преобразовали в целое число, вы могли бы это сделать. Он по-прежнему несет в себе целочисленную информацию, но эта информация недоступна при приведении. С точки зрения массива это всего лишь объект.
@LiveNLearn Я предлагаю вам включить этот комментарий в свой ответ как важный момент.
Спасибо всем. @LiveNLearn Думаю, я понял вашу точку зрения? Есть ли возможность понять, что здесь происходит, проанализировав байт-код?
Вы объявили EX3 как массив объектов, а синтаксический сахар java позволил вам не объявлять 1 и «ss» как
Objectявно (точно так же, как автобоксинг и распаковка работают сInteger <-> int). Но они передаются вObjectпри добавлении в массив, поэтому массив остается однородным. Он содержит только значения типаObject