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 .