将静态变量从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属性, lateinitconst作为字段暴露给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 
Interesting Posts