Kotlin中的单个感叹号是什么意思?我已经看过几次,特别是在使用Java API时。但我在文档和StackOverflow中都找不到它。
他们被称为platform types,他们的意思是Kotlin不知道这个值是否可以是null
,由你来决定它是否可以为空。
简而言之,问题是来自Java的任何引用都可能为null,而Kotlin在设计上是空的安全性,迫使用户对每个Java值进行空值检查,或使用安全调用(
?.
)或非空语句(!!
)。那些在纯Kotlin世界中非常方便的功能,当你必须在Kotlin / Java设置中经常使用它们时,往往会变成一场灾难。这就是我们采用激进方法并使Kotlin的类型系统在Java互操作方面更加轻松的原因:现在来自Java的引用有特别标记的类型 - Kotlin Blog
这是platform types的表示法:
T!
的意思是“T
或T?
”
用!
标记的类型称为平台类型,这是一种来自Java的类型,因此最有可能是null
。这是Kotlin编译器在调用Java时默认推断的内容(对于最基本的情况,Java方法可以通过annotated来解决这个问题)。您应该将平台类型作为可空类型处理,除非您当然知道特定的API永远不会返回null
。编译器允许将平台类型分配给可空和非空类型的变量。
[...]
T!
的意思是“T or T?
”[...]
您可以将平台类型称为“未知可空性类型”。同样重要的是要知道你不能为自己的类型使用感叹号类型,它不是Kotlin语法的一部分,它只是一个符号。
以单个感叹号!
结尾的类型名称或类名称在Kotlin中称为平台类型。当您在Kotlin中使用不包含可空性信息的旧Java代码时,您会发现它们。
例如:
Java中的@Nullable String
被Kotlin视为String?
。
Java中的@NotNull String
被Kotlin视为String
。
在Java中没有注释的String
被Kotlin认为是String!
。
您可以使用平台类型作为可空或非空。编译器将允许您调用此类型的所有方法。如何使用它们是您的责任。如果您知道该值可以为null,则应在调用其上的方法之前将其与null进行比较。如果你知道它不是null,你可以直接使用它,但是在Java中,如果你对可空性的假设是错误的,你会得到例外。
请注意,您无法在Kotlin代码中声明平台类型,它们仅来自Java代码。
在Kotlin代码中覆盖Java方法时,您可以选择声明参数并将类型返回为可空或非空。您需要明智地选择它,因为如果您决定使参数为非null,则Kotlin编译器会为这些非null参数生成非空断言。当您下次从Java访问此Kotlin代码并传递空值时,您将获得异常。
希望有助于清除您对平台类型的所有怀疑。
我已经看过几次,特别是在使用Java API时
正如s1m0nw1所述,T!
意味着T or T?
。接下来的问题是:什么是T?
?这在https://kotlinlang.org/docs/reference/null-safety.html上有很好的记录。 Kotlin不允许某些元素是null
,例如与Java不同,String
为了允许空值,我们可以将变量声明为可空字符串,写成String?:
var b: String? = "abc" b = null // ok
[...]
b?.length
如果b不为null,则返回b.length,否则返回null。这个表达式的类型是
Int?
。
来自Platform Types in Kotlin的摘录:
除了明确指定一个类型为可选(例如
Person?
)之外,Kotlin还向我们展示了另一个叫做Platform Type
的野兽,它通过放置一个感叹号来指定(例如Person!
)。当从Java等不安全平台访问代码时,出于兼容性原因而创建了此概念。通常情况下,当使用Java库时,许多方法返回SomeType!
,因为Kotlin编译器无法推断结果是否可为空。
例如:
(Mutable)Collection<T>!
仅仅意味着:“T的Java集合可能是可变的,也可能是可空的”。
希望这可以帮助。