Exposing legacy getter/setter as Kotlin property

#1

Suppose I have a legacy Java class like this:

public class MyClass {
   private String text;

   public String getText() {
      return this.text;
   }

   public void setText(String text) {
       this.text = text;
   }
}

Now in Kotlin I can do this:

val obj = MyClass()
obj.text = "something"

And this .text gets resolved to the underlying setting (and getter).

But I can’t seem to find a way to work with such a property via reflection. Is it possible to somehow expose it to a function that expects KProperty or KMutableProperty via MyClass::text or obj::text?

I can kind of get there by extending MyClass in Kotlin and adding a “redirection” property:

class MyKotlinClass : MyClass() {
    var myText: String
        get() = this.text
        set(value) {
            this.text = value
        }
}

First it’s not ideal as I effectively duplicate all the properties and try to find names that make sense. Second, it doesn’t even compile anymore for a function that expects a KProperty.

If I use MyKotlinClass::myText I get “Type mismatch. Required: KProperty. Found: KMutableProperty1”. If I use obj::myText I get “Type mismatch. Required: KProperty. Found: KMutableProperty0”.

What’s the idiomatic way of exposing a getter/setter pair from the Java side as KProperty?

#2

Unfortunately this is an area where compatibility is somewhat limited. There are a number of options. Probably the cleanest one is to create an extension property that forwards to the getter and setter so that the property can be accessed transparently. The extension property getter and setter can even be inline.

#3

From what I saw, extension properties can not be used with :: syntax

#4

If you want that, you will have to reference the getter instead, or create the lambda manually.