Ответ 1
В Java массив также является объектом.
Вы можете поместить объект подтипа в переменную супертипа. Например, вы можете поместить объект String
в переменную Object
.
К сожалению, определение массива в Java как-то нарушено. String[]
считается подтипом Object[]
, но это неправильно! Более подробное объяснение читается о "ковариации и контравариантности", но суть в этом: тип следует рассматривать как подтип другого типа, только если подтип выполняет все обязательства супертипа. Это означает, что если вы получаете объект подтипа вместо объекта супертипа, вы не должны ожидать, что поведение противоречит контракту супертипа.
Проблема в том, что String[]
поддерживает только часть контракта Object[]
. Например, вы можете читать значения Object
из Object[]
. И вы также можете читать значения Object
(которые являются объектами String
) из String[]
. Все идет нормально. Проблема заключается в другой части контракта. Вы можете поместить любой Object
в Object[]
. Но вы не можете поставить Object
в String[]
. Поэтому String[]
не следует рассматривать как подтип Object[]
, но спецификация Java говорит, что это так. И таким образом мы имеем такие последствия.
(Обратите внимание, что аналогичная ситуация появилась снова с общими классами, но на этот раз она была решена правильно. List<String>
не является подтипом List<Object>
, и если вы хотите иметь общий супертип для них, вам нужно List<?>
, который доступен только для чтения, так как это должно быть также с массивами, но это не так. И из-за обратной совместимости, это слишком поздно, чтобы изменить его.)
В первом примере функция String.split
создает объект String[]
. Вы можете поместить его в переменную Object[]
, но объект остается String[]
. Вот почему он отклоняет значение Integer
. Вам нужно создать новый массив Objects[]
и скопировать значения. Вы можете использовать функцию System.arraycopy
для копирования данных, но вы не можете избежать создания нового массива.