由於Kotlin與Java語言完全相容。 所以可以從Kotlin輕鬆地呼叫Java程式碼編寫的應用程式。 以類似的方式,Kotlin程式碼也從Java程式碼中呼叫。
在討論如何從Java程式碼呼叫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
。
檔案: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
如果想要從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檔案名更改為包類名。
MyKotlin.kt
編寫Kotlin程式碼並在頂部放置註解@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'
如果Kotlin的多個檔案使用@JvmName
註解生成相同的Java檔案名,則通常在從Java檔案呼叫時會出錯。 但是,Kotlin編譯器生成單個Java fa?ade類,其中包含生成的Java檔案以及具有相同名稱的檔案的所有宣告。 為了啟用fa?ade類,我們在所有檔案中使用@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
在頂級和類中使用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