36

Since Kotlin doesn't have primitives, how could this interface be implemented?

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

I cannot change the Java code since it's a compiled class file in a binary library.

ice1000
  • 6,406
  • 4
  • 39
  • 85

5 Answers5

27

If a single implementation, as in @zsmb13's answer, is not enough for you and you need separate implementations for the two methods in Kotlin, then you can add an intermediate interface overriding the method accepting Integer with a nullable parameter:

private interface IntermediateA : A {
    override fun get(i: Int?): Any
}

Implementing this interface instead of the original A, the Kotlin compiler will distinguish the two methods, allowing you to override them as follows:

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

If you had access to the Java code, you could fix this by adding a nullability annotation to the method accepting the boxed type:

Object get(@Nullable Integer i);

The Kotlin compiler understands different kinds of nullability annotations, here's the list.

hotkey
  • 140,743
  • 39
  • 371
  • 326
11

Implementing just one method that takes Int as its parameter works, and can be called from either Kotlin or Java.

class B : A {

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

}

If you decompile the bytecode, you'll see that the Kotlin compiler is smart enough to create both methods, with one of them just redirecting to the real implementation.

Decompiled bytecode example

One possible problem is that you can't make the method take Int?, and it will crash with a NullPointerException on the .intValue() call if it's called from Java like so:

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

I'm not sure if there's a way to solve for that use case.

Edit: hotkey's answer has rest of the answers in it.

zsmb13
  • 85,752
  • 11
  • 221
  • 226
  • What if I have two entirely different implementations depending on whether it's `int` or `Integer`? How to get that differentiation in Kotlin? – azizbekian May 23 '17 at 10:57
  • It seems like that might not be possible in this exact case. In general, you could differentiate these by declaring a method that takes `Int` to handle primitives and another that takes `Int?` that handles the boxed type. – zsmb13 May 23 '17 at 11:04
  • Fine, I got your point. But I cannot grasp why boxed one won't be immediately dispatched to `Int` provided it's value is **not** `null`. – azizbekian May 23 '17 at 11:12
  • 1
    There is a way, but it requires the Java method parameter to be annotated as `@Nullable`. With no access to the Java code, it seems to be possible only with an intermediate Java interface, see the other answer. – hotkey May 23 '17 at 11:59
  • 1
    Actually, a Kotlin intermediate interface is enough (overriding only one function with `Int?` paramater type). – hotkey May 23 '17 at 12:13
4

In Kotlin, we can declare:

  • primitive int as : Int
  • boxed int as : Int?

Your interface can be simplified to:

private interface ModifiedA : A {
    override fun get(i: Int?): Any
}

In Kotlin, if you implement this modified interface then Kotlin will provide you two methods to override. One for primitive type and another one for boxed type.

class ImplementationOfA : ModifiedA {
    override fun get(i: Int)
    override fun get(i: Int?)
}
ice1000
  • 6,406
  • 4
  • 39
  • 85
Avijit Karmakar
  • 8,890
  • 6
  • 44
  • 59
0

I write a simple demo in Java.

then convert it to Kotlin with Kotlin plugins in IntelliJ IDEA or Android Studio.

ice1000
  • 6,406
  • 4
  • 39
  • 85
dong sheng
  • 266
  • 3
  • 10
0

add these lines to implement interface in kotlin

class abc : AppCompatActivity(), interface 1, interface 2,
{
override fun get(i: Int?): Any
}
Rishita Joshi
  • 203
  • 2
  • 3
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 30 '21 at 14:40
  • How's `AppCompatActivity` relevant? – ice1000 Nov 30 '21 at 16:15