Kotlin中的单个感叹号

问题描述 投票:84回答:6

Kotlin中的单个感叹号是什么意思?我已经看过几次,特别是在使用Java API时。但我在文档和StackOverflow中都找不到它。

kotlin
6个回答
111
投票

他们被称为platform types,他们的意思是Kotlin不知道这个值是否可以是null,由你来决定它是否可以为空。

简而言之,问题是来自Java的任何引用都可能为null,而Kotlin在设计上是空的安全性,迫使用户对每个Java值进行空值检查,或使用安全调用(?.)或非空语句(!!)。那些在纯Kotlin世界中非常方便的功能,当你必须在Kotlin / Java设置中经常使用它们时,往往会变成一场灾难。

这就是我们采用激进方法并使Kotlin的类型系统在Java互操作方面更加轻松的原因:现在来自Java的引用有特别标记的类型 - Kotlin Blog


48
投票

这是platform types的表示法:

T!的意思是“TT?


11
投票

!标记的类型称为平台类型,这是一种来自Java的类型,因此最有可能是null。这是Kotlin编译器在调用Java时默认推断的内容(对于最基本的情况,Java方法可以通过annotated来解决这个问题)。您应该将平台类型作为可空类型处理,除非您当然知道特定的API永远不会返回null。编译器允许将平台类型分配给可空和非空类型的变量。

Notation for Platform Types

[...]

T!的意思是“T or T?”[...]

您可以将平台类型称为“未知可空性类型”。同样重要的是要知道你不能为自己的类型使用感叹号类型,它不是Kotlin语法的一部分,它只是一个符号。


3
投票

以单个感叹号!结尾的类型名称或类名称在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代码并传递空值时,您将获得异常。

希望有助于清除您对平台类型的所有怀疑。


2
投票

我已经看过几次,特别是在使用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?


0
投票

来自Platform Types in Kotlin的摘录:

除了明确指定一个类型为可选(例如Person?)之外,Kotlin还向我们展示了另一个叫做Platform Type的野兽,它通过放置一个感叹号来指定(例如Person!)。当从Java等不安全平台访问代码时,出于兼容性原因而创建了此概念。通常情况下,当使用Java库时,许多方法返回SomeType!,因为Kotlin编译器无法推断结果是否可为空。

例如:

(Mutable)Collection<T>! 

仅仅意味着:“T的Java集合可能是可变的,也可能是可空的”。

希望这可以帮助。

© www.soinside.com 2019 - 2024. All rights reserved.