Two compiler errors are reported in this code: one about types with NULL capability, and the other about generics.
Impossible types . Kotlin uses the null reference discipline, and since T can be created using, say, String, which makes an arr of type Array, the compiler does not allow zeros to be placed in this array. If you need zeros, you need to change the type to Array:
class GenericClass<T>() { private var arr : Array<T?>? = null { arr = Array(10, { null })
Generics . There is still a compile-time error in the above example because we are trying to build an array of unknown type T. Note that this problem also exists in Java. Kotlin, compiled into JVM byte code, entails two things:
- arguments of type generics are removed at run time,
- except for the general arguments of arrays.
This means that in byte code, Kotlin should create an array of a specific type, not an unknown type T. It can create arrays of objects whenever it sees Array, but this will not work, for example, in this case:
fun test() { fun foo(srts: Array<String?>) {
Here, in the last line, we are trying to pass Object [] where String [] is expected, and get a runtime error.
This is why Kotlin refuses to create T. arrays. You can get around this problem by explicitly suppressing the type system, i.e. using cast types:
class GenericClass<T>() { val arr : Array<T?> { arr = Array<Any?>(10, { null }) as Array<T?> } }
Here we explicitly request the creation of the Any array (compiled in Object []), and then enter it into an array from T. The compiler generates a warning, but obeys our will.
Please note that the above problematic example remains, i.e. if you pass an array created in such a way where an array of strings is expected, it does not work at runtime.