Как реализовать этот интерфейс Java в Kotlin?
Поскольку у Kotlin нет примитивов, как реализовать этот интерфейс?
public interface A {
@NotNull Object get(@NotNull Integer i);
@NotNull Object get(int i);
}
Я не могу изменить код Java, так как это скомпилированный файл класса в двоичной библиотеке.
5 ответов
Если одной реализации, как в zsmb13, вам недостаточно, и вам нужны отдельные реализации для двух методов в Kotlin, то вы можете добавить промежуточный интерфейс, переопределяющий метод, принимающий Integer
с обнуляемым параметром:
private interface IntermediateA : A {
override fun get(i: Int?): Any
}
Реализация этого интерфейса вместо оригинального A
компилятор Kotlin будет различать два метода, что позволит вам переопределить их следующим образом:
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
Если у вас был доступ к коду Java, вы могли бы это исправить, добавив аннотацию обнуляемости в метод, принимающий упакованный тип:
Object get(@Nullable Integer i);
Компилятор Kotlin понимает различные виды аннотаций обнуляемости, вот список.
Реализация только одного метода, который занимает Int
как его параметр работает, и может быть вызван из Kotlin или Java.
class B : A {
override fun get(i: Int): Any {
return "something"
}
}
Если вы декомпилируете байт-код, вы увидите, что компилятор Kotlin достаточно умен для создания обоих методов, причем один из них просто перенаправляет на реальную реализацию.
Одной из возможных проблем является то, что вы не можете заставить метод принять Int?
, и он потерпит крах с NullPointerException
на .intValue()
вызовите, если он вызывается из Java следующим образом:
B b = new B();
Integer i = null;
b.get(i);
Я не уверен, есть ли способ решить для этого варианта использования.
Изменить: ответ горячей клавиши содержит остальные ответы.
В Котлине мы можем заявить:
- примитив int как:
Int
- упакованный как:
Int?
Ваш интерфейс может быть упрощен до:
private interface ModifiedA : A {
override fun get(i: Int?): Any
}
В Kotlin, если вы реализуете этот измененный интерфейс, Kotlin предоставит вам два метода для переопределения. Один для примитивного типа, а другой для коробочного типа.
class ImplementationOfA : ModifiedA {
override fun get(i: Int)
override fun get(i: Int?)
}
Я пишу простую демонстрацию на Java.
затем конвертируйте его в Kotlin с помощью плагинов Kotlin в IntelliJ IDEA или Android Studio.
добавьте эти строки для реализации интерфейса в kotlin
class abc : AppCompatActivity(), interface 1, interface 2,
{
override fun get(i: Int?): Any
}