静态导入 Kotlin 伴生对象的方法?

14
能否在另一个类的伴生对象中导入一个方法,而不需要使用“Companion”限定符进行导入?也就是说,是否有可能说 import Bar.toFoo 而非 import Bar.Companion.toFoo,假设 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。


1
我不明白为什么你要使用 Bar().convert(toFoo()) 而不是 Bar().toFoo()。为什么它必须是静态的? - Naetmul
嗯,因为toFoo()实际上就是Java 8的Collector类之一,就像Collectors.toList()或者Collectors.toSet()一样,并且其模型也是相同的。 - Max
类似 import static example.Bar.toFoo; 这样的代码应该可以工作(因为Java不能在根包中有类,所以这里修改了例子中的包名)- 你看到了哪个编译器错误?它是在IDE中还是在构建中? - JK Ly
嗯,Java可以在根包中有类,而Kotlin没有“import static”语句。我看到的错误是“未解决的引用”。 - Max
抱歉,具体到Java的话:从未命名的包导入类型是编译时错误。但是似乎我误解了问题,因为你似乎正在尝试将伴生对象函数导入到另一个Kotlin类中。 - JK Ly
1个回答

3
与Java不同,Kotlin不允许您通过实例引用来调用静态成员。Java根据编译时声明来分配这些成员,因此在Kotlin中这样做是不被允许的。
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()

我认为这并没有回答问题。 - MageWind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接