Obviously you can’t extend the thing that does not exist. You will get the same error if you want to non-existing companion of kotlin class. There is a feature request somewhere in the tracker to automatically create empty companions in such cases, but it probably won’t work for java classes. Does it matter to you what namespace will you use to call static methods?
Does it matter to you what namespace will you use to call static methods?
I want this extension function (in a Kotlin file) to seem like a static function (in a Java class).
There is no reason to do it but I am clearly experimenting around with Kotlin and I am wondering if this is possible.
Well actually they are. Assuming you wrote the extension function in a plain file outside a class, the compiler creates a class called <filename>Kt and the function will be a static function with its first argument the receiver. When using Kotlin in a (decent) IDE, it detects that and hides the first parameter and lets you call as a normal function.
I mean that they are not visible as extensions. The idea was to upgrade Java class with some functionality. This obviously won’t work. Maybe some IDE cheats could do that, but the code itself will be really ugly.
I will not call the extension function from Java. I will call the function only from Kotlin. I wanted to seem (only to seem) like it is belonging in a Java class. I want to create an extension function and call it from Kotlin source only. As I know of, the extension functions can be called like this classInstance.functionName(). I want to create an extension function for a class and call it ClassName.functionName(). I want the extension function to resolve statically (as already does) and call it in a static way in my Kotlin source.
public class MyJavaClass {
public String derp(){
return "Hey mom!"
}
public MyJavaClass(){}
// whatever...
}
In any Kotlin .kt file just write:
fun MyJavaClass.myExtension(){ // <-- here's the extension function definition.
// Notice your java class as receiver
println("Hey! I'm an extension! Look: ${derp()}")
}
fun main(){
val myJ = MyJavaClass()
myJ.myExtension()
}
Output will be Hey! I'm an extension! Look: Hey mom!
Based on your example I could explain myself better.
I don’t want to call the extension function like MyJavaClass().myExtension(). But, I want to call the extension function like MyJavaClass.myExteension() if possible.
Indeed in the definition i wrote the receiver is the class not a particular instance of that class. On every object created from MyJavaClass you will be able to call myExtension()
I think you have some sort of confusion on how classes and objects works. I’ll try to help. Have a look here:
fun main(){
val myJ = MyJavaClass()
myJ.myExtension() // <-- this is correct. Keep in mind that you have to declare
// `myExtension()` somewhere as i did in the previous example
MyJavaClass.myExtension() // <-- this line is incorrect. You are calling a method
// as it was static, but it's not.
}
Have a look at a more complete example:
// JAVA HERE
public class A {
public String foo;
public A(){
}
}
// KOTLIN HERE
data class B(val foo: String)
fun A.extensionAlpha(){
println("Hey I'm A and foo = $foo")
}
fun B.extensionBeta(){
println("Hey I'm B and foo = $foo")
}
fun main() {
val a = A()
a.foo = "A"
val b = B("B")
a.extensionAlpha()
b.extensionBeta()
}
The output will be:
Hey I'm A and foo = A
Hey I'm B and foo = B
You could even compact all of this this way (writing all in Kotlin so it’s more compact but it would work seamlessly using classes/interfaces from Java):
interface Foo {
val foo: String
}
data class A(override val foo: String = "A"): Foo
data class B(override val foo: String = "A"): Foo
fun Foo.extension(){
println("Hey I'm ${this::class.java.simpleName} and foo = $foo")
}
fun main() {
val a = A()
val b = B()
a.extension()
b.extension()
}
If you could add a static function to a class it will be bonded to that class and it will not “pollute” the namespace at the package you are working. Probably, if a Companion object could be created automatically (as @darksnake mentioned) , this could be achieved.
I asked just to assure if this was not possible or if I have missed something!