Home > Blockchain >  Can I add Kotlin extension function to Java class?
Can I add Kotlin extension function to Java class?

Time:09-27

I'm trying to create extension function like this:

fun UHFTAGInfo.toReadUhfTagInfo(): ReadUhfTagInfo {
    return ReadUhfTagInfo(this.epc, this.count, this.rssi.toIntOrNull())
}

It is supposed to convert UHFTAGInfo (from java library) to ReadUhfTagInfo (my class in Kotlin).

I'm trying to use it like this:

UHFTAGInfo i = getUHFTAGInfo();
ReadUhfTagInfo ri = i.toReadUhfTagInfo();

At this moment my toReadUhfTagInfo function is at top level, but finally I want to put it in my ReadUhfTagInfo class, like this:

class ReadUhfTagInfo(var epc: String, var cnt: Int, var rssi: Int?)
{
    fun UHFTAGInfo.toReadUhfTagInfo(): ReadUhfTagInfo {
        return ReadUhfTagInfo(this.epc, this.count, this.rssi.toIntOrNull())
    }
}

CodePudding user response:

You can call Kotlin extension functions from Java, sure, but you can't call them with extension function syntax, you must call them like static methods. If you, for example, define

// file: Foo.kt

fun Bar.baz() { ... }

then in Java, you would call this as

FooKt.baz(bar);

CodePudding user response:

I don't think you want to have toReadUhfTagInfo as a member function on the ReadUhfTagInfo class. That would imply that, in order to convert a UHFTAGInfo to a ReadUhfTagInfo, you already need a ReadUhfTagInfo object (which will presumably go unused except to serve as the receiver object.

Extension functions defined inside a class are member extensions and essentially have two receivers.

You can declare extensions for one class inside another class. Inside such an extension, there are multiple implicit receivers - objects whose members can be accessed without a qualifier. An instance of a class in which the extension is declared is called a dispatch receiver, and an instance of the receiver type of the extension method is called an extension receiver.

If you want the extension method to act like a static method in Java (i.e. not require an instance of the enclosing class to execute), then you do the same thing we do with all static methods in Kotlin: We put it in a companion object.

class ReadUhfTagInfo(var epc: String, var cnt: Int, var rssi: Int?)
{
  companion object {
    fun UHFTAGInfo.toReadUhfTagInfo(): ReadUhfTagInfo {
      return ReadUhfTagInfo(this.epc, this.count, this.rssi.toIntOrNull())
    }
  }
}

As pointed out in the comments, this will still require the name to be imported into the current scope (as all extension methods do), but it won't require a receiver of type ReadUhfTagInfo to call anymore.

  • Related