Как реализовать этот интерфейс 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.