将静态变量从Java转换为Kotlin
我试图将下面的代码转换为Kotlin,并仍然有一个由Java使用的类(Foo)。 什么是做这种转换的正确方法?
原始Java:
public class Foo { public static final String C_ID = "ID"; public static final String C_NAME = "NAME"; public static final String[] VALUES = {"X", "Y", "Z"}; public static String[] getAll() { return new String[] {C_ID, C_NAME}; } } public class Bar { public void doStuff() { String var1 = Foo.C_ID; String[] array1 = Foo.VALUES; String[] array2 = Foo.getAll(); } }
将Foo自动转换为Kotlin
object Foo { val C_ID = "ID" val C_NAME = "NAME" val VALUES = arrayOf("X", "Y", "Z") val all: Array<String> get() = arrayOf(C_ID, C_NAME) }
问题:
Bar类不能再访问C_ID或VALUES(错误:“私人访问”)
如果我把“const”放在C_ID的前面,它可以工作,但是我不能和VALUES一样(“const”只能用在primatives或者String上)
有没有一种不同的方式我应该这样做(所以Java代码和Kotlin代码都可以访问Foo中的所有内容)?
目前的语义来自Kotlin Beta Candidate :
@JvmField和对象
我们已经制定了生成纯字段(而不是
get
/set
对)的策略更具可预测性:从现在开始,只有注解为@JvmField
属性,lateinit
或const
作为字段暴露给Java客户端。 较早的版本使用启发式方法,并无条件地在对象中创建静态字段,这违背了我们默认具有兼容二进制兼容性的API的初始设计目标。另外,单例实例现在可以通过名称
INSTANCE
(而不是INSTANCE$
)来访问。
根据这个和参考 ,有三种方法来处理来自Java的Kotlin object
属性:
-
使用
Foo.INSTANCE
。默认情况下,
object
属性不会是Java的静态字段,但Java可以通过Foo
对象实例 –Foo.INSTANCE
访问属性。所以表达式将是
Foo.INSTANCE.getC_ID()
。 -
用
@JvmStatic
注解标记一个属性:object Foo { @JvmStatic val C_ID = "ID" //... }
这将为
C_ID
生成静态getter,而不是Foo
实例getter,它将以Foo.getC_ID()
形式访问。 -
在属性声明中使用
@JvmField
注解:object Foo { @JvmField val C_ID = "ID" //... }
这将使Kotlin编译器为Java生成静态字段而不是属性。 然后在Java中,您可以将其作为静态字段来访问:
Foo.C_ID
。但它不会在你的例子中没有像
all
背景字段的属性。
对于原语,正如你所说,可以使用const
,就Java中的可见性而言,它与@JvmField
具有相同的效果。
顺便说一下,说到方法,情况是一样的,还有@JvmStatic
注解。
在你的foo类中,你可以把这些属性和方法放在一个伴随对象中:
class Foo { companion object { val C_ID:String = "ID" val C_NAME:String = "NAME" @JvmField val VALUES = arrayOf("X", "Y", "Z") fun getAll():Array<String> { return arrayOf(C_ID, C_NAME) } } }
然后你可以调用Foo.getAll()和Foo.C_ID,Foo.C_NAME和Foo.VALUES。
你应该能够访问的价值“科特林的方式”:
object Foo { val C_ID = "ID" val C_NAME = "NAME" val VALUES = arrayOf("X", "Y", "Z") val all: Array<String> get() = arrayOf(C_ID, C_NAME) } fun main(args: Array<String>) { Foo.all.forEach { it->println(it) } }
结果是:
ID NAME Process finished with exit code 0