Kotlin給Java開發者帶來最大改變之一就是廢棄了static
修飾符。與Java不同的是在Kotlin的類中不允許你聲明靜態成員或方法。相反,你必須向類中添加Companion對象來包裝這些靜態引用: 差異看起來似乎很小,但是它有一些明顯的不同。
一:companion伴生對象作用
首先,companion伴生對象是個實際對象的單例實例。你實際上可以在你的類中聲明一個單例,並且可以像companion伴生對象那樣去使用它。這就意味着在實際開發中,你不僅僅只能使用一個靜態對象來管理你所有的靜態屬性! companion
這個關鍵字實際上只是一個快捷方式,允許你通過類名訪問該對象的內容(如果伴生對象存在一個特定的類中,並且只是用到其中的方法或屬性名稱,那麼伴生對象的類名可以省略不寫)。就編譯而言,下面的testCompanion()
方法中的三行都是有效的語句。
class TopLevelClass {
companion object {
fun doSomeStuff() {
...
}
}
object FakeCompanion {
fun doOtherStuff() {
...
}
}
}
fun testCompanion() {
TopLevelClass.doSomeStuff()
TopLevelClass.Companion.doSomeStuff()
TopLevelClass.FakeCompanion.doOtherStuff()
}
Kotlin中調用方式可以看出包裹在Companion裏的方法直接用
1: 類.方法 : TopLevelClass.doSomeStuff() ,當然也可以使用最原始的
2: 類.Companion.方法 : TopLevelClass.Companion.doSomeStuff(),而此時其實是可以直接省略Companion
3:object聲明的靜態內部類用 類.內部類.方法 :TopLevelClass.FakeCompanion.doOtherStuff()
二:在java中的調用
上面方法在java中的調用如下
TopLevelClass.Companion.doSomeStuff();
TopLevelClass.FakeCompanion.INSTANCE.doOtherStuff();
和在kotlin的調用中可看出區別
1:Companion包裹的在Kotlin中調用可以選擇省略Companion,直接 類.方法,但是在java中就不能省略
2:object聲明的靜態內部類在java中多了INSTANCE 這個參數
那是不是有其他的方法讓Kotlin和java的調用可以一致呢,就涉及到了以下的第三點
三:@JvmStatic註解、@JvmField註解
@JvmField註解:用來修飾靜態變量
@JvmStatic註解:用來修飾靜態方法
還是用原來的例子,增加變量的註釋
class TopLevelClass {
companion object {
@JvmField
val BIG_INTEGER = "BigInteger.ONE"
@JvmStatic
fun doSomeStuff() {
}
}
object FakeCompanion {
@JvmField
val BIG_INTEGER = "BigInteger.ONE"
@JvmStatic
fun doOtherStuff() {
}
}
}
在java中的調用
TopLevelClass.doSomeStuff();
String s = TopLevelClass.BIG_INTEGER;
TopLevelClass.FakeCompanion.doOtherStuff();
String s1 = TopLevelClass.FakeCompanion.BIG_INTEGER;
可以看出和在kotlin的調用是沒差別的
四、在companion object中如何調用外部的成員變量
companion object
中調用非靜態的成員變量也是調用不到的,將所引用的成員變量也修飾靜態的,這樣就可以引用到了。
參考:https://blog.csdn.net/u013064109/article/details/89199478