從Java調用Kotlin代碼

由於Kotlin與Java語言完全兼容。 所以可以從Kotlin輕鬆地調用Java代碼編寫的應用程序。 以類似的方式,Kotlin代碼也從Java代碼中調用。

在討論如何從Java代碼調用Kotlin代碼之前,讓我們來看一下Kotlin文件內部的樣子。

Kotlin程序內部如何?

MyKotlin.kt 文件中創建一個簡單的main函數。

fun main(args: Array<String>){
//code  
}
fun area(l: Int,b: Int):Int{
    return l*b
}

編譯上面的Kotlin文件MyKotlin.kt 後,內部看起來像:

public class MyKotlinKt{
    public static void main(String[] args){
        //code  
    }
    public static int area(int a, int b){
        return a*b;
    }
}

Kotlin編譯器在內部添加了一個包含命名約定MyKotlinKt的包裝類。 Kotlin文件MyKotlin.kt 轉換爲MyKotlinKt,默認情況下是public。 高級別函數的默認修飾符是public,默認情況下函數轉換爲static。 由於返回類型是MyKotlin.kt 中的Unit,因此在MyKotlinKt中將其轉換爲void

從Java代碼調用Kotlin代碼

文件:MyKotlin.kt

fun main(args: Array<String>){  
//code  
}  
fun area(a: Int, b: Int):Int{
    return a*b
}

文件:MyJava.java

public class MyJava {
    public static void main(String[] args) {
        int area = MyKotlinKt.area(4,5);
        System.out.print("printing area inside Java class returning from Kotlin file: "+area);
    }
}

執行上面Java代碼,得到以下結果 -

printing area inside Java class returning from Kotlin file: 20

Kotlin文件調用Java包內的代碼

如果想要從Java類調用不同包中的Kotlin代碼,則需要在Java類中導入包含Kotlin文件名的包名,並從Java類調用Kotlin代碼。 另一種方法是指定完整路徑:packageName.KotlinFileKt.methodName()來調用。

文件:MyKotlinFileKt.kt

package mykotlinpackage

fun main(args: Array<String>) {

}
fun area(l: Int,b: Int):Int{
    return l*b
}

文件:MyJava.java

package myjavapackage;
import mykotlinpackage.MyKotlinFileKt;

public class MyJavaClass {
    public static void main(String[] args){
        int area = MyKotlinFileKt.area(4,8);
        System.out.println("printing area inside Java class returning from Kotlin file: "+area);
    }
}

執行上面Java代碼,得到以下結果 -

printing area inside Java class returning from Kotlin file: 32

使用註解@JvmName更改Kotlin文件名

使用[@JvmName](https://github.com/JvmName "@JvmName")註解將Kotlin文件名更改爲包類名。

MyKotlin.kt

編寫Kotlin代碼並在頂部放置註解[@file](https://github.com/file "@file"):JvmName("MyKotlinFileName")。 編譯Kotlin代碼後,文件名將更改爲註釋中提供的名稱(如:MyKotlinFileName)。 在訪問MyKotlin.kt的代碼時,需要使用文件名:MyKotlinFileName

文件:MyKotlin.kt

@file: JvmName("MyKotlinFileName")
package mykotlinpackage

fun main(args: Array<String>) {

}
fun area(l: Int,b: Int):Int{
    return l*b
}

文件:MyJava.java

package myjavapackage;
import mykotlinpackage.MyKotlinFileName;

public class MyJavaClass {
    public static void main(String[] args){
        int area = MyKotlinFileName.area(4,5);
        System.out.println("printing area inside Java class returning from Kotlin file: "+area);
    }
}

執行上面Java代碼,得到以下結果 -

Connected to the target VM, address: '127.0.0.1:62308', transport: 'socket'
printing area inside Java class returning from Kotlin file: 20
Disconnected from the target VM, address: '127.0.0.1:62308', transport: 'socket'

使用@JvmMultifileClass調用具有相同Java類名的多個文件方法

如果Kotlin的多個文件使用[@JvmName](https://github.com/JvmName "@JvmName")註解生成相同的Java文件名,則通常在從Java文件調用時會出錯。 但是,Kotlin編譯器生成單個Java façade類,其中包含生成的Java文件以及具有相同名稱的文件的所有聲明。 爲了激活façade類,我們在所有文件中使用[@JvmMultifileClass](https://github.com/JvmMultifileClass "@JvmMultifileClass")註解。

文件:MyKotlin1.kt

@file: JvmName("MyKotlinFileName")
@file:JvmMultifileClass
package mykotlinpackage

fun main(args: Array<String>) {

}
fun area(l: Int,b: Int):Int{
    return l*b
}

文件:MyKotlin2.kt

@file: JvmName("MyKotlinFileName")
@file:JvmMultifileClass
package mykotlinpackage


fun volume(l: Int,b: Int,h: Int):Int{
    return l*b*h
}

文件:MyJava.java

package myjavapackage;
import mykotlinpackage.MyKotlinFileName;

public class MyJavaClass {
    public static void main(String[] args){
        int area = MyKotlinFileName.area(4,5);
        System.out.println("printing area inside Java class returning from Kotlin file: "+area);
        int vol = MyKotlinFileName.volume(4,5,6);
        System.out.println("printing volume inside Java class returning from Kotlin file: "+vol);
    }
}

執行上面Java代碼,得到以下結果 -

printing area inside Java class returning from Kotlin file: 20
printing volume inside Java class returning from Kotlin file: 120

訪問Kotlin const修飾符屬性

在頂級和類中使用const修飾符註釋的Kotlin屬性在Java中轉換爲靜態字段。 這些屬性是從Java文件訪問的,稱爲static屬性。 例如:

文件:MyKotlin.kt

const val MAX = 720
object Obj {
    const val CONST = 1
}
class C {
    companion object {
        const val VERSION = "5.1.1216"
    }
}

文件:MyJava.java

public class MyJava {
    public static void main(String[] args) {
        int c = Obj.CONST;
        int m = MyKotlinKt.MAX;
        String v = C.VERSION;
        System.out.println("const => "+c+"\n, max=> "+m+"\n, version=> "+v);
    }
}

執行上面Java代碼,得到以下結果 -

const => 1
, max=> 720
, version=> 5.1.1216