I tried this, and the code didn't compile.
class GenericClass<T>() {
private var arr : Array<T>? = null
{
arr = Array<T>(10, { null })
}
}
I tried this, and the code didn't compile.
class GenericClass<T>() {
private var arr : Array<T>? = null
{
arr = Array<T>(10, { null })
}
}
There are two compiler errors reported in this code: one is about nullable types and another about generics.
Nullable types.Kotlin强制执行可空引用的规则,并且由于T可能会被实例化,例如,字符串使arr成为数组类型,编译器不允许您将空值放入该array.如果需要空值,则必须将类型更改为数组:
class GenericClass<T>() {
private var arr : Array<T?>? = null
{
arr = Array(10, { null }) // No need to specify type arguments again
}
}
Generics. The example above still has a compile-time error, because we are trying to construct an array of an unknown type T. Note that this problem exists in Java as well. Kotlin being compiled to JVM byte code entails two things:
这意味着在字节码中,Kotlin必须创建某种具体类型的数组,而不是未知类型的T.它可以在看到数组时创建对象数组,但这不起作用,例如,在这种情况下:
fun test() {
fun foo(srts: Array<String?>) {
// ...
}
val gc = GenericClass<String>()
foo(gc.arr)
}
在这里,在最后一行中,我们试图传递对象[],其中字符串[]是预期的,并得到一个运行时错误.
这就是Kotlin拒绝创建T数组的原因.您可以通过显式 suppress 类型系统来解决此问题,即使用类型转换:
class GenericClass<T>() {
val arr : Array<T?>
{
arr = Array<Any?>(10, { null }) as Array<T?>
}
}
在这里,我们显式地请求创建一个Any数组(编译为Object[]),然后将其类型转换为一个Tarray.编译器发出警告,但遵从我们的意愿.
请注意,上面的问题示例仍然存在,也就是说,如果将以这种方式创建的数组传递给预期的字符串数组,它将在运行时失败.