Как реализовать этот интерфейс Java в Котлине?
Поскольку у Котлина нет примитивов, как это можно реализовать?
public interface A {
Object get(Integer i);
Object get(int i);
}
Я не могу изменить код Java для него скомпилированный файл класса в библиотеке.
Ответы
Ответ 1
Если вам нужна одна реализация, как в @zsmb13, вам не нужны отдельные реализации для двух методов в Котлине, то вы можете добавить промежуточный интерфейс, переопределяющий метод, принимающий 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-коду, вы можете исправить это, добавив аннотацию nullability к методу, принимающему тип в штучной упаковке:
Object get(@Nullable Integer i);
Компилятор Kotlin понимает различные аннотации нулевой вероятности, здесь список.
Ответ 2
Реализация только одного метода, который принимает 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);
Я не уверен, есть ли способ решить этот случай использования.
Изменить: Ответ на горячую клавишу содержит ответы на оставшиеся ответы.
Ответ 3
В Котлине мы можем объявить:
примитивный int как: 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?)
}
Ответ 4
Я пишу простую демонстрацию в java.
затем преобразуйте его в kotlin с плагинами kotlin в idea
или Android Studio
.