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