如何将 Kotlin 的 lateinit 变量的后备字段从 Java 中隐藏?

12
在 Kotlin 中,假设我有以下类:

class MyKotlinClass {
    lateinit var field: String
}
根据文档所述:
Late-Initialized属性也会被公开为字段。该字段的可见性将与lateinit属性setter的可见性相同。
在Java中,我可以使用myKotlinClass.fieldmyKotlinClass.getField()。 我想禁用字段访问,并仅保留通过getter和setter进行访问。 如何实现此目标并保持lateinit修饰符?
3个回答

15

您可以使用@JvmSynthetic,该注释可将声明从Java中隐藏(但不会从Kotlin中隐藏)。只需对属性的后备字段进行注解

@field:JvmSynthetic
lateinit var field: String

尽管该字段在字节码中仍将保持为public,但它也将具有synthetic修饰符,这可以防止其在Java源代码中使用。然而,在运行时,该字段似乎仍然可以通过反射访问。

另请参见:关于@JvmSynthetic的另一个问题(尽管没有确定的答案)。


谢谢。这正是我所需要的。 - Michael Spitsin
@voddan,像这样:public synthetic Ljava/lang/String; s。或者你找到了从Java引用该字段的方法吗? - hotkey
@hotkey,你是完全正确的,很抱歉给你打了个“-1”。请编辑你的A(在某个地方加一个空格:)这样我就可以点赞了。 - voddan
@voddan,没问题,我更新了答案并加入了更多关于它的细节说明。 :) - hotkey
有没有办法隐藏生成的getter和setter,而不将它们设置为private? - stefana
显示剩余3条评论

2

解决这个问题的经典方法是使用属性委托

import kotlin.properties.Delegates

class MyKotlinClass {
    var field: String by Delegates.notNull()
}

这段代码完全符合您在问题中所要求的


1
感谢您提供另一种解决方案。我还查看了此讨论https://discuss.kotlinlang.org/t/notnull-delegate-vs-lateinit/1923-以了解`lateinit`和`Delegates.notNull()`之间的实际区别。 - Michael Spitsin

1
该字段的可见性是由相应属性的 setter 的可见性派生的,因此另一个选项是拥有具有非公共 setter 的属性:
lateinit var field: String
    private set

这种方法的缺点是在类外部无法访问该setter本身。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接