静态导入Kotlin Companion方法?

时间:2017-06-13 22:29:38

标签: kotlin

TL:博士;可以import另一个类的伴随对象中的方法,没有使用Companion限定导入吗?也就是说,假设import Bar.toFooimport Bar.Companion.toFoo的伴随对象上的方法,我可以说toFoo而不是Bar吗?

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

class Bar {
  static Foo toFoo() {
    return new Foo();
  }
}

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

import Bar.toFoo;

// ...
    Bar().convert(toFoo()); // like a Java 8 Collector
// ...

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

class Bar {
  companion object {
    @JvmStatic fun toFoo() = Foo()
  }
}

我们希望调用代码无需修改即可使用

import Bar.toFoo

不再有效,即使是@JvmStatic!相反,我们 将其更新为

import Bar.Companion.toFoo

我们不需要这样做 - 我们希望在不更新呼叫者的情况下将Bar类切换到Kotlin。

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

1 个答案:

答案 0 :(得分:1)

与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();
    }
}

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

但是,您可以在Bar上定义扩展功能:

fun Bar?.toFoo() = Bar.toFoo()

然后你可以打电话

val foo = fooAsBar.toFoo()