Reputation: 5081
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.
Upvotes: 15
Views: 5595
Reputation: 474
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()
Upvotes: 4