Вы не можете безопасно привести тип к супертипу или подтипу, как этот, потому что Array<String>
не квалифицируется как Array<Any>
. Если вы попытаетесь поместить Double в ваш предполагаемый Array<Any>
, это вызовет исключение, потому что фактическим типом является массив String. Массивы являются особым случаем обобщений, которые не имеют стирания типов, поэтому они привязаны к типу, с которым они были созданы.
Что вы можете сделать, это привести его к Array<out Any>
, потому что вы можете безопасно используйте это таким образом. Вы можете извлечь Strings из массива, и они будут считаться экземплярами Any. Обратное неверно. Вы не можете поместить любой экземпляр Any и его подклассов в массив String.
Когда дело доходит до List, вы можете привести его к списку с типом супертипа, и вам даже не нужно будет приводить его вручную. Это. Это безопасно, поэтому приведение может быть выполнено неявно.
val s = listOf("some string")
val upcasted: List<Any> = s // implicit cast
Так почему бы вам не выполнить приведение к List<out Any>
? Интерфейс List не имеет каких-либо функций, позволяющих вам добавлять в него материал. Он определен с помощью out
-проектированного типа в его объявлении, поэтому, когда вы набираете List<Any>
, это уже то же самое, что и List<out Any>
Если вы попытаетесь сделать это с MutableList, который принимает в него элементы и не определен с out
-проектированным типом, тогда вы столкнетесь с тем же предупреждением, что и с массивом.
val s = mutableListOf("some string")
val upcasted: MutableList<Any> = s as MutableList<Any> // warning here and implicit cast impossible
Разница между этим и массивом что есть стирание типа, поэтому у вас не будет исключения времени выполнения, если вы попытаетесь добавить не-String в этот список. Но есть вероятность скрытых ошибок, если вы не будете осторожны, поэтому предупреждение.