2017-06-13 77 views
2

tl:dr;是否有可能import方法在另一個類的伴侶對象中,沒有通過Companion來驗證導入的合格?也就是說,是否有任何可能的方式我可以說import Bar.toFoo而不是import Bar.Companion.toFoo,假設toFooBar的伴侶對象上的方法?靜態導入Kotlin Companion方法?


我們正在從Java遷移到Kotlin。我們班是這樣的:

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

,然後使用它,從出現這種情況是科特林一類,我們這樣說:

import Bar.toFoo; 

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

當我們轉換Bar到科特林,它看起來像這樣:

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

我們想調用代碼不修改工作,但是

import Bar.toFoo 

不再有效,即使使用@JvmStatic!相反,我們將其更新爲

import Bar.Companion.toFoo 

我們寧願沒有這樣做 - 我們要切換酒吧類科特林而不更新呼叫者。

想法?我們使用Kotlin 1.1.2-2。

+0

我不知道爲什麼你嘗試使用'欄()的原因轉換。 (toFoo())'而不是'Bar()。toFoo()'。爲什麼它必須是靜態的? – Naetmul

+0

那麼,因爲'toFoo()'實際上*是一個Java 8 Collector類,就像'Collectors.toList()'或者'Collectors.toSet()'一樣,並且是以同樣的方式建模的。 – Max

+0

類似於'import static example.Bar.toFoo;'應該可以工作(從您的示例中更改包,因爲Java不能在根包中包含類) - 您看到了什麼編譯器錯誤?它在IDE中還是在構建中? –

回答

0

與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不支持它。

然而,你可以在酒吧定義一個擴展功能:

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

然後就可以調用

val foo = fooAsBar.toFoo()