kotlin - 静态导入 Kotlin Companion 方法?

标签 kotlin

tl:博士;是否可以 import 另一个类的伴生对象内的方法,无需使用 Companion 限定导入?也就是说,假设 toFoo 是一种方法,我是否可以说 import Bar.toFoo 而不是 import Bar.Companion.toFooBar 的伴生对象上?


我们正在将一个类从 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。

最佳答案

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

关于kotlin - 静态导入 Kotlin Companion 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44532601/

相关文章:

android - Unity3D maintemplate.gradle Kotlin依赖项

junit - 模拟挂起函数在 Mockito 中返回 null

dependency-injection - 有没有办法在 kotlin kodein 中创建一个可以产生 null 的工厂绑定(bind)?

reflection - 在 Kotlin 中按名称动态获取函数

Kotlin 协程比线程花费更长的时间

enums - Kotlin 枚举中的循环引用

kotlin - Kotlin 中的偏函数应用

android - 如何在 Kotlin 中自定义 Android Studio 的导入顺序以忽略它们是否是 "static"导入?

kotlin - 在声明挂起函数时传达预期的线程类型(IO、默认、主线程)

android - Firebird 和 Android JDBC 驱动程序