Probably I miss something very simple, but let's imagine I have this extension method in Kotlin:
fun Any.log(message: String) {
println(this.javaClass.simpleName message)
}
Is it possible to call it from the static method in Java class?
Note. From the regular instance method, I can do
MyExtensionsKt.log(this, "This is a log message")
But the static method doesn't have an object instance.
CodePudding user response:
You could just pass a random Object
in:
MyExtensionsKt.log(new Object(), "This is a log message");
Of course, this will produce a log message that starts with Object
, not the name of the current class.
To produce a log message that starts with the name of the current class, you would need to either create a new, temporary instance of the current class:
// suppose the static method is in "SomeClass"
MyExtensionsKt.log(new SomeClass(), "This is a log message");
or change the implementation of the log
method to be a bit smart about its receiver. For example, if it is found that it is a Class
, then just directly use its name as the prefix for the log message.
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");
If you cannot do either of those things, then I would suggest that you not use a static method. How about the singleton pattern instead?
Example:
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"!
Side note:
Singletons are also how Kotlin's object
s are implemented in the JVM.
object Foo {
fun foo() {
this.log("This is a log message")
}
}
When you call Foo.foo()
, it may seem like you are calling a "static" method, but you are really just calling Foo.INSTANCE.foo()
. Because of this, this
is available in Kotlin object
s.
CodePudding user response:
When you invoke that extension function in Kotlin code, it will look something like:
myObject.log("hello world")
To do the same thing from Java code, you would write:
MyExtensionsKt.log(myObject, "hello world")
The reason the code in your question works in an instance method is that this
is a reference to the enclosing object. However, in a static method, there's no enclosing instance, so you'll need to provide some other object reference.