静态导入Kotlin Companion方法?

Max*_*Max 6 kotlin

TL:博士; 是否有可能import在另一个类的伴随对象内部的方法,而不用导入资格Companion?也就是说,有没有可能的方式来import Bar.toFoo代替import Bar.Companion.toFoo,假设toFoo是一个方法Bar的伴侣对象?


我们正在将一个类从Java迁移到Kotlin.我们班看起来像这样:

class Bar {
  static Foo toFoo() {
    return new Foo();
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,为了使用它,从恰好是Kotlin的类中,我们会说:

import Bar.toFoo;

// ...
    Bar().convert(toFoo()); // like a Java 8 Collector
// ...
Run Code Online (Sandbox Code Playgroud)

当我们转换Bar为Kotlin时,它看起来像这样:

class Bar {
  companion object {
    @JvmStatic fun toFoo() = Foo()
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,我们希望调用代码无需修改即可工作

import Bar.toFoo
Run Code Online (Sandbox Code Playgroud)

即使使用@JvmStatic,也不再有效!相反,我们必须将其更新为

import Bar.Companion.toFoo
Run Code Online (Sandbox Code Playgroud)

我们宁愿不必这样做 - 我们希望在不更新调用者的情况下将Bar类切换到Kotlin.

思考?我们正在使用Kotlin 1.1.2-2.

tan*_*o24 3

与 Java 不同,Kotlin 不允许您通过实例引用调用静态成员。Java 根据编译时声明来分派这些成员,因此在

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在Java中,fooAsBar.toFoo()实际上会调用Bar.toFoo()(声明的类型)而不是Foo.toFoo()(运行时类型)。这是误解的根源,并且不是良好的编程实践,因此 Kotlin 不支持它。

但是,您可以在 Bar 上定义扩展函数:

fun Bar?.toFoo() = Bar.toFoo()
Run Code Online (Sandbox Code Playgroud)

然后你可以打电话

val foo = fooAsBar.toFoo()
Run Code Online (Sandbox Code Playgroud)