Ответ 1
Тип List
возвращаемый asList
- Arrays$ArrayList
. Метод toArray
в JDK 8 для этого класса:
@Override
public Object[] toArray() {
return a.clone();
}
Но в JDK 9+ это:
@Override
public Object[] toArray() {
return Arrays.copyOf(a, a.length, Object[].class);
}
В обоих случаях String[]
передается asList
, но в случае JDK 8 он клонируется, который сохраняет свой тип массива (String[]
), а в JDK 9+ он копируется с использованием Arrays.copyOf
с явным новым тип массива Object[]
.
Эта разница означает, что в JDK 8 Arrays.asList("a", "b").toArray().getClass()
возвращает String[]
а в JDK 9+ возвращает Object[]
, поэтому в JDK 9+ ваш выражение будет оцениваться как false
.
Причиной этого изменения является JDK-6260652 с мотивировкой:
В документации Коллекции утверждается, что
collection.toArray()
"идентичен по функции"
collection.toArray(new Object[0]);
Однако реализация
Arrays.asList
не следует этому: если он создан с массивом подтипа (например,String[]
), егоtoArray()
вернет массив того же типа (потому что он используетclone()
) вместоObject[]
.Если позже кто-то попытается сохранить не-Strings (или что-то еще) в этом массиве,
ArrayStoreException
.
Так что это изменение было сделано, чтобы исправить предыдущее поведение.
Если это проблема для вас, в соответствующей заметке о выпуске предлагается это в качестве обходного пути:
Если эта проблема возникает, перепишите код для использования формы с одним аргументом
toArray(T[])
и предоставьте экземпляр нужного типа массива. Это также устранит необходимость в приведении.String[] array = list.toArray(new String[0]);