【Kotlin 初学者】Java和Kotlin互操作
作者簡介:CSDN博客專家、華為云·云享專家認證
系列專欄:Kotlin 初學者
五星好評:左側點一下(網頁端),移動端:https://bbs.csdn.net/topics/603956616
目錄
一、Kotlin調用Java
1.1 互操作性與可空性
1.2 類型映射
1.3 屬性訪問
二、Java調用Kotlin
2.1 @JvmName
2.2 @JvmField
2.3 @JvmStatic
2.4 @JvmOverloads
2.4.1 未使用@JvmOverloads注解
2.4.2 使用@JvmOverloads注解
2.5 @Throws
2.6 函數類型操作
一、Kotlin調用Java
1.1 互操作性與可空性
????????Java世界里所有對象都是null,當一個Kotlin函數返回String類型值,它是可空的。
建立一個 Java 類
class?JavaUser?{public?String?userInfo(){return?"Java-帥次";}//返回nullpublic?String?family(){return?null;} }Kotlin 調用 Java 方法
fun?main()?{var?user?=?JavaUser()println(user.userInfo())////使用時報錯:NullPointerException //????println(user.family().length)//平臺類型,可能為nullvar?fam?=?user.family()//當fam為null時,fam?.length返回nullprintln(fam?.length)//null }1.2 類型映射
????????代碼運行時,所有的映射類型都會重新映射回對應的Java類型。
Java定義屬性類型
class?JavaUser?{public?String?name?=?"Java";... }Kotlin 查看類型
fun?main()?{println(user.name.javaClass)//查看類型:class?java.lang.String }1.3 屬性訪問
????????剛才使用public修飾屬性,在Kotlin可以直接調用,那么我們用private呢?
Java定義屬性
class?JavaUser?{private?int?age?=18;public?int?getAge()?{return?age;}public?void?setAge(int?age)?{this.age?=?age;}... }Kotlin 使用
fun?main()?{println(user.age)user.age?=?12println(user.age)println(user.age.javaClass) }????????如果僅使用private而不設置get/set方法 Kotlin是無法調用的,當設置了get/set方法。Kotlin可以直接調用其屬性,而不用調用get/set方法(默認調用get/set方法),如下圖:
二、Java調用Kotlin
2.1 @JvmName
????????可以使用JvmName注解指定編譯類的名字。
2.1.1 在KotlinUser文件中定義kotlinUserInfo()函數
package?com.scc.kotlin.primary.jandkfun?kotlinUserInfo()?=?"來自Kotlin的招呼"2.1.2 在JavaMain使用main方法調用Kotlin的kotlinUserInfo()函數
package?com.scc.kotlin.primary.jandk;class?JavaMain?{public?static?void?main(String[]?args)?{System.out.println(KotlinUserKt.kotlinUserInfo());//來自Kotlin的招呼} }????????覺得KotlinUserKt不好看,咱們給它換個名字,或者說起個別名。
2.1.3 在Kotlin文件最上方添加@JvmName
????????這個必須寫在文件最頂部。
@file:JvmName("SCKotlin") package?com.scc.kotlin.primary.jandk fun?kotlinUserInfo()?=?"來自Kotlin的招呼"2.1.4 調用@JvmName設置的名字
????public?static?void?main(String[]?args)?{ //????????System.out.println(KotlinUserKt.kotlinUserInfo());//來自Kotlin的招呼System.out.println(SCKotlin.kotlinUserInfo());//來自Kotlin的招呼}2.2 @JvmField
????????在Java里,不能直接訪問Kotlin定義的字段(如下:name),所以必須調用getName,然而,你可以給Kotlin屬性添加@JvmField注解,暴露它的支持字段給Java調用者,從而避免使用getter方法。
class?KotlinSc{@JvmFieldvar?name?=?"Kotlin-SC"var?age?=?13 }????????KotlinSc的name屬性添加了@JvmField注解,Java可以直接調用,age屬性未添加@JvmField注解,所以Java無法直接調用,當然你可以通過get/set方法調用age屬性。如下圖:
class?JavaMain?{public?static?void?main(String[]?args)?{KotlinSc?kotlinSc=new?KotlinSc();System.out.println(kotlinSc.name);//Kotlin-SC} }2.3 @JvmStatic
????????對函數使用該注解,kotlin編譯器將生成另一個靜態方法;
????????對屬性使用該注解,kotlin編譯器將生成其他的setter和getter方法;
????????這個注解的作用其實就是消除Java調用Kotlin的companion object對象時不能直接調用其靜態方法和屬性的問題.
注意:此注解只能在companion object中使用
class?KotlinSc?{...//伴生對象companion?object{var?height?=?178fun?evaluate()?=?"SC是一個學習Kotlin的小渣渣"} }在kotlin中可直接使用,但是在Java中則必須
//在kotlin中可直接使用 fun?main()?{println(KotlinSc.height.toString().plus("CM"))//178CMprintln(KotlinSc.evaluate())//SC是一個學習Kotlin的小渣渣 } //在Java中則相對復雜一些。public?static?void?main(String[]?args)?{KotlinSc?kotlinSc=new?KotlinSc();System.out.println(kotlinSc.Companion.getHeight()+"CM");//178CMSystem.out.println(kotlinSc.Companion.evaluate());//SC是一個學習Kotlin的小渣渣}給伴生對象的函數使用@JvmStatic注解,屬性還是使用
class?KotlinSc?{...companion?object{@JvmFieldvar?height?=?178@JvmStaticfun?evaluate()?=?"SC是一個學習Kotlin的小渣渣"} }Java調用添加注解的函數和屬性
????public?static?void?main(String[]?args)?{KotlinSc?kotlinSc=new?KotlinSc();System.out.println(KotlinSc.height+"CM");//178CMSystem.out.println(KotlinSc.evaluate());//SC是一個學習Kotlin的小渣渣}2.4 @JvmOverloads
????????JvmOverloads注解協助產生Kotlin函數的重載版本。設計一個可能會暴露給Java用戶使用的API時,記得使用@JvmOverloads注解,這樣,無論你是Kotlin開發者還是Java開發者,都會對這個API的可靠性感到滿意。
2.4.1 未使用@JvmOverloads注解
????????定義一個未使用@JvmOverloads注解的Kotlin函數
fun?kotlinEat(bread:?String?=?"巧克力面包",?meat:?String?=?"雞翅")?{println("$bread-搭配-$meat-美極了") }????????使用kotlin調用,一點問題沒有,妥妥的。
fun?main()?{kotlinEat();//巧克力面包-搭配-雞翅-美極了kotlinEat("橙香面包")//橙香面包-搭配-雞翅-美極了kotlinEat(meat?=?"羊肉")//巧克力面包-搭配-羊肉-美極了kotlinEat("奶油長桿面包","牛肉")//奶油長桿面包-搭配-牛肉-美極了 }????????使用Java調用,僅能調用傳入兩個參數的方法,而不能像Kotlin那樣隨意調用。
2.4.2 使用@JvmOverloads注解
????????我們在給kotlinEat(bread: String = "巧克力面包", meat: String = "雞翅")函數添加@JvmOverloads注解。
@JvmOverloads fun?kotlinEat(bread:?String?=?"巧克力面包",?meat:?String?=?"雞翅")?{println("$bread-搭配-$meat-美極了") } ????public?static?void?main(String[]?args)?{SCKotlin.kotlinEat("Java牌面包");//Java牌面包-搭配-雞翅-美極了}????????為什么會這樣?咱們看看:
????????未使用@JvmOverloads注解
????????使用@JvmOverloads注解,此處截圖不全,兩個參數的方法沒截取到,感興趣的自己去玩玩。
????????使用@JvmOverloads注解后強迫該函數重載,這樣Java就可以進行不同場景調用了。
2.5 @Throws
????????使用@Throws注解,聲明這個方法要檢查Exception。
//這里的Throws是必須添加的,要不Java那邊無法捕捉這個異常 @Throws(IOException::class) fun?kotlinEatException(){println("吃東西嗆住了")throw?IOException() }????????編譯成Java代碼,如下:
????public?static?void?main(String[]?args)?{try?{SCKotlin.kotlinEatException();//吃東西嗆住了}?catch?(IOException?e)?{System.out.println(e);//java.io.IOExceptione.printStackTrace();}}2.6 函數類型操作
????????函數類型和匿名函數能提供高效的語法用于組件間的交互,是Kotlin編程語言里比較新穎的特性。
????????他們簡潔的語法因->操作符而實現,但Java8之前的JDK版本并并不支持lambda表達式。
????????在Java里,Kotlin函數類型使用FunctionN這樣的名字的接口來表示的,FunctionN中的N代表值參數目。這樣的Function接口從Function0到Function22(23個),每一個FunctionN都包含一個invoke函數,專用于調用函數類型函數,所以,任何時候需要調一個函數類型,都用它調用invoke。
val?hair?=?{colorHair:String?->println(?"頭發染成?$colorHair?即可") }val?hairTwo?=?{colorHair:String,lengthHair:Int?->println(?"頭發染成$colorHair,剪至$lengthHair-厘米即可") } ????????Function1<String,?Unit>?hair?=?SCKotlin.getHair();hair.invoke("紅色");//頭發染成?紅色?即可Function2<String,?Integer,?Unit>?hairTwo?=?SCKotlin.getHairTwo();hairTwo.invoke("藍色",8);//頭發染成藍色,剪至8-厘米即可Function接口從Function0到Function22(23個)
總結
以上是生活随笔為你收集整理的【Kotlin 初学者】Java和Kotlin互操作的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 比特位计数
- 下一篇: 漫画 | 浏览器一个比一个“无耻”
