20

这可能有点难以描述,所以我将尝试举一个具体的例子来说明我正在尝试做的事情。

假设我们有一个 Facade 接口和类(在 Java 中),像这样:

interface FacadeInterface<T> {
    void method(String from, String via);
}

class Facade<T> implements FacadeInterface<T> {
    private Class<T> mClazz;

    public Facade(Class<T> clazz) {
        mClazz = clazz;
    }

    @Override
    public void method(String from, String via) {
        System.out.println("Method called from " + from + " via " + via);
    }
}

在我的应用程序中,我需要多个单例来保存外观的一个实例。真正的外观有额外的设置/配置参数,但这些参数在这里无关紧要。

在我开始使用 kotlin 之前,我会有一个类,它包含一个门面的静态实例(不是真正的单例,但在我的情况下,它具有类似的目的),它代理对门面的调用,如下所示:

public class Singleton {
    private static final FacadeInterface<String> sFacade = new Facade<>(String.class);

    private Singleton() {
    }

    public static void method(String from, String via) {
        sFacade.method(from, via);
    }
}

现在,有了 Kotlin,我们有了类委托,可以让我写这样的东西:

object SingletonKt : FacadeInterface<String> by Facade(String::class.java)

这很棒 - 不再需要样板文件,我可以像调用java 一样SingletonKt 从 KotlinSingleton类调用:

Singleton.method("Kotlin", "Singleton")
SingletonKt.method("Kotlin", "SingletonKt")

SingletonKt 但是,当我使用from Java时会出现一个小问题。然后我必须指定INSTANCE

Singleton.method("Java", "Singleton");
SingletonKt.INSTANCE.method("Java", "SingletonKt");

我知道@JvmStatic注释,但是我可以将它放在SingletonKt文件中而不会导致编译错误的唯一位置是之前FacadeInterface,它似乎并没有起到作用。

有没有办法设置这个类委托,以便我可以从 Java 调用它,就好像它是一个静态方法一样,而不引入创建代理方法的样板SingletonKt(这会破坏类委托的目的)?

4

2 回答 2

7

可惜不可能!

Kotlin 委托是减少样板代码的好方法。但它伴随着无法实际访问类体内的委托。

您面临的第二个问题@JvmStatic实际上比第一个问题更严重,并且在手动实施委托时也适用于您:

覆盖成员不能是对象中的“@JvmStatic”

因此,您可以将其委托给对象上的 a ,而不是method()通过唯一的方式公开。这仍然与您的意图不同,但接近它。INSTANCEstaticMethod()

object SingletonKt : FacadeInterface<String> by Facade(String::class.java)
    @JvmStatic fun staticMethod(from: String, via: String) = method(from, to)
}
于 2018-05-16T10:25:53.877 回答
2

我不知道是否可以在 Kotlin 的对象中将委托方法作为静态方法。

但是,由于您对创建代理类的单例感兴趣,您可以在 Kotlin 中使用包级常量:

val SingletonKt : FacadeInterface<String> = Facade(String::class.java)

现在,您可以SingletonKt.method像在 Java 中一样调用。请注意,您需要在 Java 中使用静态导入才能使用该SingletonKt常量。

这也允许您使用lazy仅在需要时创建单例(或在本例中为实例)等功能。

于 2018-05-12T16:36:02.200 回答