Kotlin: How can I use delegated properties in Java?
Asked Answered
W

2

6

I know that you can't use the delegated property syntax in Java, and won't get the convenience of "overriding" the set/get operators as in Kotlin, but I'd still like to use an existing property delegate in Java.

For instance, a simple delegate of an int:

class IntDelegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>) = 0
}

In Kotlin of course we can use this like so:

val x by IntDelegate()

But how can we use IntDelegate in some form in Java? This is the start, I believe:

final IntDelegate x = new IntDelegate();

And then using the functions directly. But how can I use the getValue function? What do I pass for its parameters? How do I get a KProperty for Java field?

Warnerwarning answered 17/7, 2017 at 23:53 Comment(1)
why did you need to call such a feature? it is visible & used by kotlin only.Tova
B
5

If you really want to know how Kotlin delegated property looks under the hood in Java, here it is: in this example a property x of a java class JavaClass is delegated to the Delegates.notNull standard delegate.

// delegation implementation details
import kotlin.jvm.JvmClassMappingKt;
import kotlin.jvm.internal.MutablePropertyReference1Impl;
import kotlin.jvm.internal.Reflection;
import kotlin.reflect.KProperty1;

// notNull property delegate from stdlib
import kotlin.properties.Delegates;
import kotlin.properties.ReadWriteProperty;


class JavaClass {
    private final ReadWriteProperty<Object, String> x_delegate = Delegates.INSTANCE.notNull();
    private final static KProperty1 x_property = Reflection.mutableProperty1(
            new MutablePropertyReference1Impl(
                JvmClassMappingKt.getKotlinClass(JavaClass.class), "x", "<no_signature>"));

    public String getX() {
        return x_delegate.getValue(this, x_property);
    }

    public void setX(String value) {
        x_delegate.setValue(this, x_property, value);
    }
}

class Usage {
    public static void main(String[] args) {
        JavaClass instance = new JavaClass();
        instance.setX("new value");
        System.out.println(instance.getX());
    }
}

However I wouldn't recommend to use this solution, not only because of the boilerplate required, but because it relies heavily on the implementation details of the delegated properties and kotlin reflection.

Blackmon answered 19/7, 2017 at 2:52 Comment(0)
W
1

I know that you can't use the delegated property syntax in Java, and won't get the convenience of "overriding" the set/get operators as in Kotlin, but I'd still like to use an existing property delegate in Java.

No, just like what you said in start, it does not exist in Java. But if you insist on doing it, you can do similar things.

public interface Delegate<T> {
    T get();
    void set(T value);
}

public class IntDelegate implements Delegate<Integer> {
    private Integer value = null;

    @Override
    public void set(Integer value) {
        this.value = value;
    }

    @Override
    public Integer get() {
        return value;
    }
}

final Delegate<Integer> x = new IntDelegate();

Delcare x in interface allows you to have different implementation.

Weiss answered 18/7, 2017 at 6:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.