Kotlin:我该如何在Java中使用委托属性?

6

我知道在Java中无法使用委托属性语法,并且不会像Kotlin那样方便地“覆盖”set/get运算符,但我仍然想在Java中使用现有的属性委托。

例如,一个简单的int委托:

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

当然,在 Kotlin 中我们可以这样使用:
val x by IntDelegate()

但是我们如何在Java中以某种形式使用IntDelegate呢? 我认为这是一个起点:

final IntDelegate x = new IntDelegate();

然后直接使用函数。但是我该如何使用 getValue 函数?我需要传递什么参数?如何为Java字段获取 KProperty


为什么你需要调用这样的特性呢?它只能被 Kotlin 看到和使用。 - holi-java
2个回答

5
如果你真的想知道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 反射的实现细节。


1
我知道在Java中不能使用委托属性语法,也无法像Kotlin那样方便地“覆盖”set/get操作符,但我仍然想在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();

在接口中声明x可以让你拥有不同的实现方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接