如何从 Java 静态方法中使用接收者调用 Kotlin 扩展函数?

How can I call Kotlin extension function with receiver from the Java static method?

可能我错过了一些非常简单的东西,但让我们想象一下我在 Kotlin 中有这个扩展方法:

fun Any.log(message: String) {
    println(this.javaClass.simpleName + message)
}

是否可以从 Java class 中的 static 方法调用它?

注意从常规实例方法,我可以做到

MyExtensionsKt.log(this, "This is a log message")

但是静态方法没有对象实例。

当您在 Kotlin 代码中调用该扩展函数时,它将类似于:

myObject.log("hello world")

要在 Java 代码中做同样的事情,您可以这样写:

MyExtensionsKt.log(myObject, "hello world")

您问题中的代码在实例方法中工作的原因是 this 是对封闭对象的引用。但是,在静态方法中,没有封闭实例,因此您需要提供一些其他对象引用。

您可以将随机 Object 传递给:

MyExtensionsKt.log(new Object(), "This is a log message");

当然,这将产生一条以 Object 开头的日志消息,而不是当前 class.

的名称

要生成以当前 class 名称开头的日志消息,您需要为当前 class 创建一个新的临时实例:

// suppose the static method is in "SomeClass"
MyExtensionsKt.log(new SomeClass(), "This is a log message");

或更改 log 方法的实现,使其接收者更加智能。比如发现是一个Class,那么就直接用它的名字作为日志信息的前缀即可。

fun Any.log(message: String) {
    val prefix = if (this is Class<*>) {
        this.simpleName
    } else {
        this.javaClass.simpleName
    }
    println(prefix + message)
}

// then in SomeClass, you can do:

MyExtensionsKt.log(SomeClass.class, "This is a log message");

如果您做不到这两件事,那么我建议您不要使用静态方法。改用单例模式怎么样?

示例:

private static final SomeClass INSTANCE = new SomeClass();
public static final SomeClass getInstance() { return INSTANCE; }

// now you can have instance methods, and have access to "this"!

旁注:

单例也是 Kotlin 的 object 在 JVM 中的实现方式。

object Foo {
    fun foo() { 
        this.log("This is a log message")
    }
}

当您调用 Foo.foo() 时,您可能看起来像是在调用“静态”方法,但实际上您只是在调用 Foo.INSTANCE.foo()。因此,this 在 Kotlin objects.

中可用