Kotlin为Android和静态最终的内部类

我试图在Kotlin上重写我的Android应用程序,并且在转换ContentProvider契约类时遇到了问题。 所以我有简单的合同类(默认的东西,如内容类型和内容uris被忽略):

public final class Contract { public static final class Contacts { public static final String NAME = "Name" public static final String BIRTH = "Birth" public static final String IMAGE = "Image" } } 

如果我理解正确,在Kotlin我们没有静态成员。 相反,我们有“伴侣对象”。 所以转换成Kotlin后,我有这样的代码:

 object BirthdayContract { class Contacts : BaseColumns { companion object { val NAME = "Name" val BIRTH = "Birth" val IMAGE = "Image" } } } 

但是,当我试图访问字段像Contract.Contacts.NAME,我有错误:“名称有私人访问”。 改变可见性修改器没有效果。 那么有什么方法可以在Kotlin中使用这样的契约类,还是保留在Java中呢?

UPD我认为我应该澄清 – 我的来电代码也在Kotlin。 问题出在@JvmField批注。 有了它,我可以直接访问静态成员,而无需调用getters。

NAME是一个属性,默认情况下它的后台有私人访问权限。 但是由于它是一个属性,所以它有一个getter: getNAME()

由于这不是自然访问Java中的常量的方式,所以有几种直接公开该字段的方法:

  1. constconst val NAME = "Name"
  2. @JvmField批注: @JvmField val NAME = "Name"

要将常量作为字段显示,请使用@JvmField对其进行@JvmField

 class Contacts { companion object { @JvmField val NAME = "Name" @JvmField val BIRTH = "Birth" @JvmField val IMAGE = "Image" } } 

那么你可以像这样从Java使用它们:

 String name = Contacts.NAME; 

一旦所有的代码都在Kotlin中,你可以删除@JvmField注解。

你可以用@JvmStatic来做到这一点

 object BirthdayContract { class Contacts : BaseColumns { companion object { @JvmStatic val NAME = "Name" @JvmStatic val BIRTH = "Birth" @JvmStatic val IMAGE = "Image" } } } //Java BirthdayContract.Contacts.Companion.getNAME() 

到目前为止,我看不出有什么好的理由来扩展BaseColumns,所以更好的选择是

 object BirthdayContract { object Contacts { const val NAME = "Name" const val BIRTH = "Birth" const val IMAGE = "Image" } } //Java BirthdayContract.Contacts.NAME 

底线是kotlin中的嵌套对象看起来不干净。 请考虑简化您的代码

考虑使用普通对象

 object Contract { object Contacts { val NAME = "Name" val BIRTH = "Birth" val IMAGE = "Image" } } 

这应该完全填入您的初始Java代码。

在最近的稳定Kotlin版本公众是默认的知名度。

可选地,您可以为编译时常量添加const关键字,以便在注释中可用: https : //kotlinlang.org/docs/reference/properties.html#compile-time-constants

@JvmStatic注解是针对Java-Interop的,如果你打算去完整的kotlin,你将不需要它。