gratis descargar compiler kotlin

descargar - kotlin vs scala



¿Cómo superar el error de “misma firma JVM” al implementar una interfaz Java? (7)

¡Podemos hacer esto!

package com.example.mykotlin import android.support.v7.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) tv.text = "Hello MyKotlin" tv.textSize = 20.0f } }

Con el siguiente código, recibo el siguiente error en IntelliJ IDEA 13.1.6 y Kotlin plugin 0.11.91.AndroidStudio.3:

Platform declaration clash: The following declarations have the same JVM signature (getName()Ljava/lang/String;): • public open fun getName(): kotlin.String? • internal final fun <get-name>(): kotlin.String?

Clase de Java, JavaInterface.java :

public interface JavaInterface { public String getName(); }

Clase de Kotlin, KotlinClass.kt

public class KotlinClass(val name: String?) : JavaInterface

He intentado anular el método ''getter'' agregando override fun getName(): String? = name override fun getName(): String? = name , pero que produce el mismo error.

Puedo ver una solución al hacer esto en su lugar:

public class KotlinClass(val namePrivate: String?) : JavaInterface { override fun getName(): String? = namePrivate }

Pero en mi caso del mundo real tengo una serie de propiedades para implementar y también necesito configuradores. Hacer esto para cada propiedad no parece muy Kotlin-ish. ¿Qué me estoy perdiendo?


Hacer que la variable sea private resuelve el problema.

public class KotlinClass(private val name: String?) : JavaInterface


Hemos encontrado que para usar los mismos nombres sin chocar, ctor args debe ser privado Y aún debe anular los métodos de interfaz. No necesita campos de respaldo adicionales . Además, la asignación del cuerpo de la expresión no se repetirá, por lo que puede usar esa sintaxis de forma segura.

Interfaz de Java

interface IUser { String getUserScope(); String getUserId(); }

Clase de kotlin

class SampleUser(private val userScope: String, private val userId: String) : IUser { override fun getUserId() = userId override fun getUserScope() = userScope }


Otra solución es declarar las propiedades en una clase abstracta de Kotlin, luego escribir una clase java pequeña que amplíe KotlinClass e implemente JavaInterface.

// JavaInterface.java public interface JavaInterface { int getFoo(); void setFoo(int value); } // KotlinClass.kt abstract class KotlinClass(open var foo : Int = 0) { } // JavaAdapter.java class JavaAdapter extends KotlinClass implements JavaInterface { // all code in KotlinClass, but can''t implement JavaInterface there // because kotlin properties cannot override java methods. }


Podría usar @JvmField para indicar al compilador que no genere getter / setter, y puede implementar sus setters y getters. Con esto, su código funciona bien en Java (como atributo getter / setter) y Kotlin como propiedad

Ejemplo: JAVA :

public interface Identifiable<ID extends Serializable> { ID getId(); }

KOTLIN :

class IdentifiableImpl(@JvmField var id: String) :Identifiable<String> { override fun getId(): String { TODO("not implemented") } }


Si tiene control directo sobre la interfaz, el mejor enfoque es escribir la interfaz en Kotlin. A continuación, puede escribir su clase

public class KotlinClass(override val name: String?) : KotlinInterface

y sigue haciéndolo referencia desde cualquier código Java usando la misma interfaz que antes. Esto se ve mucho mejor que establecer todas las propiedades en privado y anular la función de obtención. Obviamente, si no puede migrar la interfaz a Java porque no la posee, entonces esa parece ser la única solución.


public interface JavaInterface { public String getName(); } public class KotlinClass(val namePrivate: String?) : JavaInterface { private var name = namePrivate override fun getName(): String? { return name } }