下面的代码如何编译没有错误?
var linkedList: MutableList<Int> = java.util.LinkedList()
当
java.util.LinkedList
类合约显然没有实现 Kotlin 接口时 MutableList
?
在您的示例中,编译器没有推断任何内容。 You 告诉编译器您的
linkedList
变量将被视为 MutableList<Int>
。编译器允许这样做,因为 java.util.LinkedList
是 Java List
接口的实现,它映射到 Kotlin List
或 MutableList
接口。
根据 Tenfour04 提供的 documentation,java 中的
List<T>
是映射类型,映射到 Kotlin List<T>
或 MutableList<T>
- 选择权取决于您。
请注意,这里使用的是单词 type,而不是 class。您所做的只是告诉编译器您希望将此变量视为
MutableList<Int>
- 就是这样。文档中的这句话强化了这个想法:
映射仅在编译时重要,运行时表示保持不变。
因此,通过将变量声明为可变变量或其他变量,您只需使用 Kotlin 映射类型屏蔽底层类 (java.util.LinkedLink)。
我们已经知道
java.util.LinkedList
默认是可变的。所以做这些
val immutableLinkedList: List<Int> = java.util.LinkedList<Int>()
val mutableLinkedList: MutableList<Int> = java.util.LinkedList<Int>()
完全有效。在前一种情况下,由于您已通知编译器
immutableLinkedList
只是类型 List<Int>
(请记住 - 您只能这样做,因为此 Kotlin 类型映射到 LinkedList
的父类型),那么您将不会能够添加或从中删除,即使实际的运行时实现在技术上允许这样做。
这些机制的存在是为了帮助保持类型安全并明确您正在使用的结构类型。如果您使用 Kotlin 工作,那么将您的 linkedList 注释为 kotlin 类型是 good
MutableList
,因为很明显这个列表实际上是可变的。
另一方面,您可以想象列表的实现实际上很重要的某种情况,因此您可以选择完全删除类型注释并让编译器将其视为
java.util.LinkedList
。
val myLinkedList = java.util.LinkedList<Int>()