new method implement create java kotlin kotlin-interop

java - method - new object kotlin



¿Cómo implementar esta interfaz Java en Kotlin? (4)

Como Kotlin no tiene primitivas, ¿cómo podría implementarse esta interfaz?

public interface A { @NotNull Object get(@NotNull Integer i); @NotNull Object get(int i); }

No puedo cambiar el código Java ya que es un archivo de clase compilado en una biblioteca binaria.


En Kotlin, podemos declarar:

  • int primitivo como: Int
  • en caja int como: Int?

Su interfaz se puede simplificar para:

private interface ModifiedA : A { override fun get(i: Int?): Any }

En Kotlin, si implementa esta interfaz modificada, Kotlin le proporcionará dos métodos para anularla. Uno para el tipo primitivo y otro para el tipo de caja.

class ImplementationOfA : ModifiedA { override fun get(i: Int) override fun get(i: Int?) }


Escribo una demostración simple en Java.

luego conviértalo a Kotlin con los complementos de Kotlin en IntelliJ IDEA o Android Studio.


La implementación de un solo método que toma Int como su parámetro funciona, y se puede llamar desde Kotlin o Java.

class B : A { override fun get(i: Int): Any { return "something" } }

Si descompilas el bytecode, verás que el compilador Kotlin es lo suficientemente inteligente como para crear ambos métodos, con uno de ellos simplemente redirigiendo a la implementación real.

Un posible problema es que no puedes hacer que el método tome Int? , y se bloqueará con una NullPointerException en la llamada a .intValue() si se llama desde Java de esta forma:

B b = new B(); Integer i = null; b.get(i);

No estoy seguro si hay una manera de resolver para ese caso de uso.

Edit: la respuesta de hotkey tiene el resto de las respuestas en ella.


Si una implementación única, como en la respuesta de @zsmb13 , no es suficiente para usted y necesita implementaciones separadas para los dos métodos en Kotlin, entonces puede agregar una interfaz intermedia que reemplace el método que acepta el Integer con un parámetro que puede ser nulo:

private interface IntermediateA : A { override fun get(i: Int?): Any }

Al implementar esta interfaz en lugar de la A original, el compilador de Kotlin distinguirá los dos métodos, lo que le permitirá anularlos de la siguiente manera:

class C : IntermediateA { override fun get(i: Int) = "primitive" override fun get(i: Int?) = "boxed" }

val a: A = C() println(a.get(1)) // primitive println(a.get(1 as Int?)) // boxed

Si tuviera acceso al código de Java, podría solucionarlo agregando una anotación de nulabilidad al método que acepta el tipo de caja:

Object get(@Nullable Integer i);

El compilador de Kotlin comprende diferentes tipos de anotaciones de nulabilidad, aquí está la lista .