如何从 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 object
s.
中可用
可能我错过了一些非常简单的东西,但让我们想象一下我在 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 object
s.