天天看點

kotlin--與Java互操作

對于以前的Java老項目,想要使用kotlin,全部轉換帶來的成本代價太大了,而官方也提供了慢慢過渡到kotlin的方法,使得Java和kotlin可以互通

一、互操作性和可空性

1.Java中所有的對象都可能為空

操作Java對象時,我們有必要加上判空符

Java:

public class MyClass {
    public String value;
    
    public String getCanNullValue(){
        return value;
    }
}           

複制

kotlin:

fun main() {
    val my = MyClass()
    val value =  my.getCanNullValue()
    println(value?.capitalize()) 
}           

複制

2.類型映射

代碼運作時,所有的映射類型都會重新映射成原來的Java類型

fun main() {
    val my = MyClass()
    my.value = "a123"
    val value =  my.getCanNullValue()
    println(value.javaClass) 
}           

複制

結果:

class java.lang.String

二、屬性、異常互操作

1.屬性通路

我們可以直接使用 "= " 對Java屬性進行指派了,對于受保護的屬性,Java類需要實作對應的get、set方法

Java:

public class MyClass {
    private String value;
    
    public String getCanNullValue(){
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}           

複制

kotlin:

fun main() {
    val my = MyClass()
    my.value = "a123"
}           

複制

2.@JvmName

kotlin頂層函數,在Java中都被當作靜态方法

kotlin:

package com.aruba.mykotlinapplication.jtok

fun getKotlinMessage(): String {
    return "hello, i'm kotlin"
}           

複制

Java:

package com.aruba.mykotlinapplication.jtok;

public static void main(String[] args) {
    System.out.println(JtokKt.getKotlinMessage());
}           

複制

如果你不滿意kotlin在Java中的類名,可以使用@JvmName修改它

kotlin:

@file:JvmName("MyKotlin")

package com.aruba.mykotlinapplication.jtok

fun getKotlinMessage(): String {
    return "hello, i'm kotlin"
}           

複制

這樣在Java中就可以用MyKotlin調用getKotlinMessage函數了

3.@JvmField

在Java中不能直接通路kotlin類的屬性,必須調用get方法,如果想要直接使用可以在kotlin的屬性上面加上@JvmField注解

class JavaToKotlin {
    @JvmField
    val info = "Hello"
}           

複制

4.@JvmOverloads

kotlin函數中可以給入參預設值,然後調用的時候不必傳入,Java不行,如果想要Java調用時,也支援,使用@JvmOverloads注解,它會幫助kotlin産生函數的重載版本

kotlin:

@JvmOverloads
fun prinltInfo(name: String, age: Int = 1) {
    println("$name $age")
}           

複制

Java:

public static void main(String[] args) {
        MyKotlin.prinltInfo("jack");
        MyKotlin.prinltInfo("jack", 20);
    }           

複制

5.@JvmStatic

@JvmField注解還能使Java用來以靜态方式擷取伴生對象的屬性

@JvmStatic則允許Java直接調用伴生對象的函數

class JavaToKotlin {
    @JvmField
    val info = "Hello"

    companion object {
        @JvmField
        val max: Int = 200

        @JvmStatic
        fun loadConfig(): String {
            return "loading config"
        }
    }
}           

複制

6.@Throws

Java和kotlin存在異常處理的差異,使用@Throws,可以讓Java知道如何處理異常

kotlin:

@Throws(IOException::class)
fun throwException() {
    throw IOException()
}           

複制

kotlin中調用Java可能會出現異常的方法,則可以直接使用try catch

三、函數類型

Java中沒有函數類型,是以,在Java裡,kotlin函數類型使用FunctionN這樣的名字的接口來表示,N代表入參的個數,一共有24個這樣的接口,從Function0到Function23,每個接口都包含一個invoke函數,調用匿名函數需要調用invoke

kotlin:

val funcp: (String) -> String = {
    it.capitalize()
}           

複制

Java:

public static void main(String[] args) {
        Function1 funcp = MyKotlin.getFuncp();
        System.out.println(funcp.invoke("abc"));
    }           

複制