如何从 Java 中隐藏 Kotlin 的 lateinit var 支持字段?
How to hide Kotlin's lateinit var backing field from Java?
在 Kotlin 中,假设我有 class:
class MyKotlinClass {
lateinit var field: String
}
根据docs:
Late-Initialized properties are also exposed as fields. The visibility of the field will be the same as the visibility of lateinit property setter.
我可以在 java 中使用 myKotlinClass.field
或 myKotlinClass.getField()
代码。我想禁用字段访问并仅保留通过 getter 和 setter.
的访问权限
我怎样才能做到这一点并保留 lateinit 修饰符?
您可以使用 属性 的 @JvmSynthetic
that hides declarations from Java (and not from Kotlin). Just annotate the backing field:
@field:JvmSynthetic
lateinit var field: String
虽然该字段将在字节码中保留 public
,但它也将具有 synthetic
修饰符,这会阻止它在 Java 源中使用。但是,该字段似乎仍然可以在运行时通过反射访问。
另请参阅:另一个 (尽管那里没有明确的答案)。
lateinit
字段的可见性源自相应 属性 的 setter 的可见性,因此另一种选择是让 属性 具有非 public setter:
lateinit var field: String
private set
这种方法的缺点是 setter 本身在 class 之外变得不可访问。
这个问题的经典解决方案是使用 property delegation:
import kotlin.properties.Delegates
class MyKotlinClass {
var field: String by Delegates.notNull()
}
此代码完全符合您在问题中的要求
在 Kotlin 中,假设我有 class:
class MyKotlinClass {
lateinit var field: String
}
根据docs:
Late-Initialized properties are also exposed as fields. The visibility of the field will be the same as the visibility of lateinit property setter.
我可以在 java 中使用 myKotlinClass.field
或 myKotlinClass.getField()
代码。我想禁用字段访问并仅保留通过 getter 和 setter.
我怎样才能做到这一点并保留 lateinit 修饰符?
您可以使用 属性 的 @JvmSynthetic
that hides declarations from Java (and not from Kotlin). Just annotate the backing field:
@field:JvmSynthetic
lateinit var field: String
虽然该字段将在字节码中保留 public
,但它也将具有 synthetic
修饰符,这会阻止它在 Java 源中使用。但是,该字段似乎仍然可以在运行时通过反射访问。
另请参阅:另一个
lateinit
字段的可见性源自相应 属性 的 setter 的可见性,因此另一种选择是让 属性 具有非 public setter:
lateinit var field: String
private set
这种方法的缺点是 setter 本身在 class 之外变得不可访问。
这个问题的经典解决方案是使用 property delegation:
import kotlin.properties.Delegates
class MyKotlinClass {
var field: String by Delegates.notNull()
}
此代码完全符合您在问题中的要求