tl:dr; Is it possible to import
a method inside a companion object of another class, without qualifying the import with Companion
? That is, is there any possible way I can say import Bar.toFoo
instead of import Bar.Companion.toFoo
, assuming toFoo
is a method on Bar
's companion object?
We're migrating a class from Java to Kotlin. Our class looks like this:
class Bar {
static Foo toFoo() {
return new Foo();
}
}
And then, to use it, from a class that happens to be Kotlin, we say something like:
import Bar.toFoo;
// ...
Bar().convert(toFoo()); // like a Java 8 Collector
// ...
When we convert Bar
to Kotlin, it looks like this:
class Bar {
companion object {
@JvmStatic fun toFoo() = Foo()
}
}
We'd like the calling code to work without modification, however
import Bar.toFoo
no longer works, even with @JvmStatic! Instead, we have to update it to
import Bar.Companion.toFoo
which we'd rather not have to do -- we want to switch the Bar class to Kotlin without updating the callers.
Thoughts? We're using Kotlin 1.1.2-2.
companion object is how you define static variables/methods in Kotlin. You are not supposed to create a new instance of Retrofit / ApiService each time you execute a request, however.
In order to implement a static method in Kotlin, we will take the help of "companion objects". Companion objects are the singleton objects whose properties and functions are tied to a class but not to the instance of that class. Hence, we can access them just like a static method of the class.
To create a companion object, you need to add the companion keyword in front of the object declaration. The output of the above code is “ You are calling me :) ” This is all about the companion object in Kotlin. Hope you liked the blog and will use the concept of companion in your Android application.
Answer: Companion object is not a Singleton object or Pattern in Kotlin – It's primarily used to define class level variables and methods called static variables. This is common across all instances of the class.
Unlike Java, Kotlin does not allow you to call static members via instance reference. Java dispatches these members based on the compile time declaration, so in
class Bar {
static Foo toFoo() { return new Foo(); }
}
class Foo extends Bar {
static Foo toFoo() { return new Foo(); }
}
class Baz {
void test() {
Bar fooAsBar = new Foo();
Foo foo = fooAsBar.toFoo();
}
}
In Java, fooAsBar.toFoo()
will actually call Bar.toFoo()
(the declared type) and not Foo.toFoo()
(the runtime type). This is a source of misunderstanding and not good programming practice, so Kotlin does not support it.
However, you can define an extension function on Bar:
fun Bar?.toFoo() = Bar.toFoo()
Then you can call
val foo = fooAsBar.toFoo()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With