Как реализовать этот интерфейс Java в Котлине?

Поскольку у Котлина нет примитивов, как это можно реализовать?

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

Я не могу изменить код Java, поскольку это скомпилированный файл класса в библиотеке.

Если одной реализации, как и в ответе @ zsmb13 , недостаточно для вас, и вам нужны отдельные реализации для двух методов в Kotlin, тогда вы можете добавить промежуточный интерфейс, переопределяющий метод, принимающий Integer с параметром nullable:

 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-коду, вы можете исправить это, добавив аннотацию обнуления к методу, принимающему тип boxed:

 Object get(@Nullable Integer i); 

Компилятор Kotlin понимает различные аннотации нулевой вероятности, вот список .

Реализация только одного метода, который принимает Int как его параметр, работает и может быть вызван либо из Kotlin, либо из Java.

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

Если вы декомпилируете байт-код, вы увидите, что компилятор Kotlin достаточно умен, чтобы создать оба метода, причем один из них просто перенаправляется на реальную реализацию.

Декомпилированный пример байт-кода

Одна из возможных проблем заключается в том, что вы не можете заставить метод принимать Int? , и он выйдет из .intValue() с помощью NullPointerException в .intValue() если он вызывается из Java следующим образом:

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

Я не уверен, есть ли способ решить этот случай использования.

Изменить: ответ на горячую клавишу содержит ответы на оставшиеся ответы.

В Котлине мы можем заявить:

primitive int as: Int

boxed int as: 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 в idea или Android Studio .

Intereting Posts
Kotlin переопределяет набор элементов и получает Параметрированные тесты JUnit5 на уровне класса TimeZone не показывает Альтернативы полем бокса или расширению ВСЕХ строк в Котлине? Может ли поле быть перенесено в не нулевую версию? Котировка класса данных Котлина с измененным значением var ArrayBroadcastChannel: второй абонент не обновляет пользовательский интерфейс Как объявить параметр функции для приема функций, которые вы выбрали? Ввод / вывод дженериков для абстрактного контейнерного инструмента в Котлине? Обработчик ошибок по умолчанию RxJava Нечетное поведение TestObserver при подписке на тему Обработка аннотации kotlin: проверьте, задан ли TypeElement из класса kotlin Синтаксис Котлина для вывода общего супертипа из подтипа Запуск модульных тестов не вызывает изменений Тестирование с помощью spek и обмен некоторыми базовыми тестовыми примерами для базовых классов