Kotlin 为什么泛型类型属性可以为null?
我正在尝试使用泛型类型的Kotlin 为什么泛型类型属性可以为null?,kotlin,Kotlin,我正在尝试使用泛型类型的lateinit不可空属性创建一个参数化类: class Test<T> { private lateinit var t : T private lateinit var s : String } 类测试{ 私有lateinit变量t:t 私有lateinit变量s:String } 后者是允许的,但前者是不允许的。编译器返回以下错误: 错误:(7,11)“lateinit”修饰符不允许用于可为空的属性 由于我没有声明t?,我不明白为什
lateinit
不可空属性创建一个参数化类:
class Test<T> {
private lateinit var t : T
private lateinit var s : String
}
类测试{
私有lateinit变量t:t
私有lateinit变量s:String
}
后者是允许的,但前者是不允许的。编译器返回以下错误:
错误:(7,11)“lateinit”修饰符不允许用于可为空的属性
由于我没有声明t?
,我不明白为什么会这样
默认上限(如果未指定)为Any?
()
换句话说,当您使用T
时,Kotlin假设这可能是任何类型,无论是原语、对象还是可为空的引用
要解决此问题,请添加一个上限类型:
class Test<T: Any> { ... }
类测试{…}
对类型参数的可空性有以下说明
类型参数的可空性:
默认情况下,的所有类型参数
Kotlin中的函数和类可以为null。任何类型,包括
可为空的类型,可以替换为类型参数;在这种情况下,,
允许使用类型参数作为类型的声明
null,即使类型参数T没有以问题结尾
马克
如何使类型参数不为null
要使类型参数为非null,需要指定一个非null
它的上限。这将拒绝将可为null的值作为参数
请注意,类型参数是
如果要将类型标记为可空,则需要在末尾加上问号,并且
没有问号的类型是非空的。下一节显示
可空性的另一个特例:来自Java的类型
代码
T、 当用作类型参数时,始终为null。(所有类型参数都可以为空)。您不需要声明
t?
,只需要声明t
。要使用声明上限,请执行此操作公共类Foo
(任何
都不可为空)可为空的类型参数
Any?
是Kotlin中所有类型的超类型。因此,当您没有为类型参数t
指定任何上限时,默认边界是any?
例如:
类测试{}
与
类测试{}
这导致在以下示例中,T
可为空:
class Test<T> {
private var t : T // T can have a nullable type
}
class Test<T : Any> {
private var t: T // T is non-null
private var t2: T? // T can be used as nullable
}
具有T:Any
的泛型类型只能使用非空类型参数进行实例化,并防止使用可空类型参数进行实例化:
val test: Test<Int> = Test() // OK
val test: Test<Int?> = Test() // OK
val test: Test<Int> = Test() // OK
val test: Test<Int?> = Test() // Error
值得注意的是,如果根据业务逻辑有一种更具体的类型,那么您可以使用一种更具体的类型。例如,如果希望上界为T:Any
,则可以使用T:SomeProduct
。它只需要是非空的
这将确保类的用户不能使用可为null的类型参数进行实例化,并且您对lateinit var
始终为非null的假设将成立
就这样!希望能有所帮助。顺便说一句,语法
T?
是不允许的,所以技术上没有不一致。T?
允许在T
中使用,而不是声明T
。所以valx:T?
是有效的。您可以阅读关于T的更多信息吗?在这里
class Test<T : Any> {
private lateinit var t: T
}