Котлин: Как я могу использовать делегированные свойства в Java?

Я знаю, что вы не можете использовать синтаксис делегированного свойства в Java и не получите удобства "переопределения" операторов set / get, как в Kotlin, но я все же хотел бы использовать существующий делегат свойства в Java.

Например, простой делегат типа int:

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

В Kotlin, конечно, мы можем использовать это так:

val x by IntDelegate()

Но как мы можем использовать IntDelegate в какой-то форме в Java? Это начало, я считаю,

final IntDelegate x = new IntDelegate();

А потом с помощью функций напрямую. Но как я могу использовать getValue функционировать? Что я передам по своим параметрам? Как мне получить KProperty для поля Java?

2 ответа

Решение

Если вы действительно хотите знать, как выглядит делегированное свойство Kotlin в Java, вот оно: в этом примере свойство x из класса Java JavaClass делегирован Delegates.notNull стандартный делегат.

// 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());
    }
}

Однако я бы не рекомендовал использовать это решение не только из-за необходимого шаблона, но и потому, что оно сильно зависит от деталей реализации делегированных свойств и отражения kotlin.

Я знаю, что вы не можете использовать синтаксис делегированного свойства в Java и не получите удобства "переопределения" операторов set/get, как в Kotlin, но я все же хотел бы использовать существующий делегат свойства в Java.

Нет, как и в начале, он не существует в Java. Но если вы настаиваете на этом, вы можете делать подобные вещи.

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 позволяет вам иметь различную реализацию.

Другие вопросы по тегам