Convierta variables estáticas de Java a Kotlin

Estoy intentando convertir el siguiente código en Kotlin Y todavía tengo una de las classs (Foo) que usa Java. ¿Cuál es la forma correcta de hacer esta conversión?

Original 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(); } } 

Conversión automática de Foo a 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) } 

Problema:

La class de barra ya no puede acceder a C_ID o VALUES (error: "acceso privado")

si pongo "const" delante de C_ID, funciona … pero no puedo hacer lo mismo con VALUES ("const" SOLAMENTE se puede usar en primativos o String)

¿Hay alguna manera diferente en que debería estar haciendo esto (para que tanto el código de Java como el de Kotlin puedan acceder a todo en Foo)?

La semántica actual proviene de Kotlin Beta Candidate :

@JvmField y objects

Hemos hecho que la estrategia para generar campos puros (a diferencia de los pares get / set ) sea más pnetworkingecible: a partir de ahora, solo las properties anotadas como @JvmField , lateinit o const se exponen como campos a los clientes de Java. Las versiones anteriores usaban heurística y creaban campos estáticos en objects incondicionalmente, lo que va en contra de nuestro objective de layout inicial de tener API aptas para compatibilidad binaria de forma pnetworkingeterminada.

Además, las instancias de singleton ahora son accesibles con el nombre INSTANCE (en lugar de INSTANCE$ ).

De acuerdo con esto y con la reference , hay tres forms de trabajar con properties de un object Kotlin de Java:

  • Use Foo.INSTANCE .

    Por defecto, las properties del object no serán campos estáticos para Java, pero Java puede acceder a las properties a través de la instancia del object FooFoo.INSTANCE .

    Entonces la expresión será Foo.INSTANCE.getC_ID() .

  • Marque una propiedad con la anotación @JvmStatic :

     object Foo { @JvmStatic val C_ID = "ID" //... } 

    Esto generará un getter estático para C_ID lugar de un getter de instancia de Foo que será accesible como Foo.getC_ID() .

  • Use la anotación @JvmField en la statement de propiedad:

     object Foo { @JvmField val C_ID = "ID" //... } 

    Esto hará que el comstackdor de Kotlin genere un campo estático para Java en lugar de propiedad. Luego, en Java, puede acceder a él como un campo estático: Foo.C_ID .

    Pero no funcionará en properties sin campos de respaldo como all en su ejemplo.

Para primitivos, como dijiste, uno puede usar const que tendrá el mismo efecto que @JvmField en términos de visibilidad en Java.

Por cierto, cuando se trata de methods, la situación es la misma, y ​​hay @JvmStatic anotación @JvmStatic para ellos.

En tu class de foo puedes poner esas properties y el método dentro de un object complementario:

 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) } } } 

Luego puede llamar a Foo.getAll (), a Foo.C_ID, a Foo.C_NAME y a Foo.VALUES.

Debería poder acceder a los valores "the kotlin way":

 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) } } 

Como resultado:

 ID NAME Process finished with exit code 0 
  • Crear un propio DataSource con properties de resorte
  • En TornadoFX, ¿cómo puedo hacer que una propiedad cambie cuando cambian otras properties?
  • En TornadoFX, ¿cómo puedo vincular las properties de BigDecimal a otra propiedad de BigDecimal usando objectBinding?
  • Al crear una interfaz en Kotlin, ¿importa si las properties tienen get / set?
  • Kotlin: cómo acceder a las properties en el constructor
  • Propiedad protegida abstracta Kotlin
  • Kotlin delegar propiedad por perezoso que es hilo local
  • Kotlin - Inicialización de propiedad usando "por perezoso" vs. "tardío"
  • ¿Cómo implementar una propiedad que proviene de una fuente determinada hasta que se establece directamente en Kotlin?
  • Función de extensión Kotlin en propiedad mutable
  • No se puede usar getter personalizado con propiedad delegada