下面的kotlin代码
val nameHash get() = name.hashCode()
可以编译成java如下
public final int getNameHash() {
return name.hashCode();
}
Run Code Online (Sandbox Code Playgroud)
并且属性 nameHash 消失。然而,当 val 更改为 var 时,编译器会说“属性必须初始化” var 和 val 之间更深层次的区别是什么?
kotlin编译器如何知道val应该是属性还是函数
就Kotlin语言而言,val表示属性,而不是函数。但是,这两个属性声明之间存在差异:
val nameHash get() = name.hashCode()
var nameHash get() = name.hashCode()
Run Code Online (Sandbox Code Playgroud)
那就是第一个属性没有支持字段。具有支持字段的属性必须以一种或另一种方式初始化,例如:
var nameHash = 0 // for example
get() = name.hashCode()
Run Code Online (Sandbox Code Playgroud)
这就是您的代码var无法编译的原因。
如果您询问为 Kotlin 属性生成支持字段时的情况,它们会在规范中列出:
但是,仅在以下情况下才为属性创建支持字段
- 属性没有自定义访问器;
- 属性有一个默认访问器;
- 属性有一个自定义访问器,并且它使用
field属性;- 可变属性具有自定义 getter 或 setter,但不能同时具有两者。
在这些情况下,您的财产需要支持字段。您var nameHash满足最后一种情况,因为它是“可变属性”。如果您val改为使用,它就不再是可变属性,并且不满足任何这些情况。
直观上,没有 setter 的可变属性需要一个支持字段,因为必须能够设置该属性。当它没有设置器时,如何设置它?那么,Kotlin 编译器通过生成一个支持字段并仅设置该支持字段来解决这个问题。