序言
kotlin的初衷本來就是為了快速生成Javascript而開發(fā),但是Google在與Java的官司過后,毅然決然決定更換Android語言體系,不再采用Java,于是kotlin被其采用。
面對kotlin成為Google的新寵,Android界起先是一片嘩然的。然而后來……

0.Kotlin真香
kotlin之所以成了Google的親兒子,無非就是以下幾點:
簡潔、優(yōu)雅
安全、快速
函數(shù)與屬性的擴展
兼容java(也就是可直接通過jvm執(zhí)行)
強大的lambda、強大的語法糖、強大的判NULL規(guī)則
1.kotlin、java互調(diào)
好了,接入今天的正軌!
在我的前兩篇文章中其實就已經(jīng)可以看出kotlin與java的互調(diào),只是當時我并沒有講解。
首先,創(chuàng)建今天的項目:【Kt3】

從上圖就可以看到,我們之前的項目所用一直都是 Java|IDEA
接下來,我們分別創(chuàng)建兩個包java和kt并分別在各自包下創(chuàng)建JavaFile.java和KtFile.kt兩個文件

一. Kotlin調(diào)用Java
JavaFile.java中我們寫下

接下來我們在KtFile.kt中寫下main函數(shù)

如上圖,代碼提示中已經(jīng)出現(xiàn)了JavaFile這個類,再看包名cn.xinidi.java沒錯,就是我們自定義的包名。
然后我們就可以試著調(diào)用剛剛寫好的sayHello方法。


成功執(zhí)行!同樣我們可以看到圖中的執(zhí)行程序就是Java.exe
二. Java調(diào)用Kotlin
好了,kotlin既然能夠直接調(diào)用java,那么我們再來看java調(diào)用kotlin
修改代碼
Kt:

Java:

運行結(jié)果:

可以看到,已經(jīng)成功運行了!

所以!Kotlin與Java到底是什么關(guān)系?為什么Kotlin能直接調(diào)用Java?

讓我把java代碼直接粘貼到Kotlin文件中(很神奇的,你別不信)
嗯?這段英文什么意思?(我英語差啊沒過四級,看不懂?。。?/p>
剪貼板的內(nèi)容來自java文件,你要不要把它轉(zhuǎn)換成Kotlin代碼?
哈哈,憑借我的撇腳英語連懵帶猜,大概意思應(yīng)該是這樣吧!
我們點一下yes

好的!如我所愿,它直接變成了Kotlin代碼
那么同樣!我把Kotlin代碼復(fù)制到j(luò)ava文件呢?
試試?試試就試試!

保險起見,我首先注釋掉了main函數(shù)。
嗯?為啥沒變?
退回上一步?。?!

好了吧!java是可以直接復(fù)制過來轉(zhuǎn)成Kotlin代碼的。
但是Kotlin轉(zhuǎn)Java代碼就不能這用了!那怎么轉(zhuǎn)?
看我操作!



好的?。。。∵@下java代碼出來了!
但是……?這也太花了!

那我們這樣,只轉(zhuǎn)一個方法

這就好理解多了吧!

默認給了一個
public final class KtFileKt類然后就是剛剛的
sayHello方法
至于中間的那條紅色下劃線……就是IDEA報的錯誤,說的是public類與文件名不一致。
為什么又多出來這么多呢?誰知道Kotlin是怎么想的。
好了這個問題不宜深究,因為誰閑的沒事將二者代碼來回轉(zhuǎn)換?明顯不是腦子what了嘛。
而且,kotlin的產(chǎn)物是由jvm執(zhí)行的?。。?!
那表示什么?.class文件嘛!
我們打開項目的out文件夾看看。

看看,這是啥!
就這樣了!本小節(jié)完了!
4. 關(guān)于java中靜態(tài)物與Kotlin中的靜態(tài)物
眾所周知!在java中存在一個static關(guān)鍵字,它存在的目的就是將一個類中的成員靜態(tài)化,跟隨jvm的執(zhí)行而執(zhí)行。
可在kotlin中,沒有static的概念!
那么我們想要直接靜態(tài)調(diào)用一個成員該怎么去實現(xiàn)呢?
根據(jù)文檔,我整理了以下
- 伴生對象
companion object
首先我們來看java中的靜態(tài)實現(xiàn)方式
public class JavaFile {
public static final String TEST_FIELD = "我是java中的靜態(tài)成員常量!";
...
}
然鵝kotlin中的寫法則是
class KtFile {
//伴生對象(可以直接理解為靜態(tài)方法)
companion object {
fun sayOk() {
println("Kotlin say Ok!!")
}
}
}
那么二者有何不同?
在剛剛的kotlin轉(zhuǎn)java操作中其實已經(jīng)有了結(jié)果。

我們來分析上圖:
首先是一個public final class KtFile
接下來靜態(tài)(static)了一個成員內(nèi)部類
public static final KtFile.Companion Companion = ...
KtFile.Companion類中我們發(fā)現(xiàn)了我們所寫的sayOk方法
然后再回到我們Java調(diào)用Kotlin的步驟中

如圖,正是調(diào)用了我們靜態(tài)內(nèi)部類的Companion對象中的sayOk方法。
那么我們在kotlin中頁需要一個TEST_FIELD呢?該怎么寫?
class KtFile {
//伴生對象(可以直接理解為靜態(tài)方法)
companion object {
const val TEST_FIELD = "我是Kotlin中的成員常量"
fun sayOk() {
println("Kotlin say Ok!!")
}
}
}
直接寫!
轉(zhuǎn)成java后:

至此,kotlin中的靜態(tài)實現(xiàn)就完成了
當然!除了上面companion object的還有以下寫法:
companion object MyStatic{...}
當然MyStatic并非是固定的,它存在的目的就是為了取代默認的Companion,你可以自己隨便取名,它就是一個常量名而已。
5. 總結(jié)
kotlin可以直接與java互相調(diào)用,而且代碼之間可以互相轉(zhuǎn)換(但是沒事不要瞎轉(zhuǎn))。
kotlin編譯后的參悟同樣是
.class文件,可以通過jvm(java虛擬機)直接調(diào)用運行。kotlin中,靜態(tài)物的生成是使用伴生對象
companion object實現(xiàn),默認的對象名是Companion,可自行定義。
最后留一個小問題:
companion object {
val TEST_FIELD_1 = "我是Kotlin中的成員常量1"
const val TEST_FIELD_2 = "我是Kotlin中的成員常量2"
}
上述兩個常量的區(qū)別(別給我整些沒用的啊,常量名、常量值、修飾符不同,我都知道的)。