Java可以很容易的調用kotlin代碼
1屬性
比如kotlin有var firstName: String
其實等同於在Java中下面的定義
private String firstName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
2.Package-Level函數
kotlin代碼
// example.kt
package demo
class Foo
fun bar() {
}
在Java調用如下
// Java
new demo.Foo();
demo.ExampleKt.bar();
可以通過@file:JvmName註釋告訴Java,比如
//kotlin代碼
@file:JvmName("DemoUtils")
package demo
class Foo
fun bar() {
}
//Java調用
// Java
new demo.Foo();
demo.DemoUtils.bar();
如果在同一自動生成的類(包名和類名一致)囊括了多個kotlin文件則需要使用@file:JvmMultifileClass
,比如
// oldutils.kt
@file:JvmName("Utils")
@file:JvmMultifileClass
package demo
fun foo() {
}
// newutils.kt
@file:JvmName("Utils")
@file:JvmMultifileClass
package demo
fun bar() {
}
在Java中調用
// Java
demo.Utils.foo();
demo.Utils.bar();
3.對象實例的字段(fields)
可以通過@JvmField修飾,比如
//kotlin
class C(id: String) {
@JvmField val ID = id
}
// Java
class JavaClient {
public String getID(C c) {
return c.ID;
}
}
4.靜態字段
4.1 使用@JvmField修飾
//kotlin
class Key(val value: Int) {
companion object {
@JvmField
val COMPARATOR: Comparator<Key> = compareBy<Key> { it.value }
}
}
// Java
Key.COMPARATOR.compare(key1, key2);
// public static final field in Key class
4.2使用lateinit修飾
//kotlin
object Singleton {
lateinit var provider: Provider
}
// Java
Singleton.provider = new Provider();
// public static non-final field in Singleton class
4.3使用const修飾
//kotlin
// file example.kt
object Obj {
const val CONST = 1
}
class C {
companion object {
const val VERSION = 9
}
}
const val MAX = 239
//java
int c = Obj.CONST;
int d = ExampleKt.MAX;
int v = C.VERSION;
5.靜態方法
通過@JvmStatic修飾
//kotlin
class C {
companion object {
@JvmStatic fun foo() {}
fun bar() {}
}
}
//java
C.foo(); // works fine
C.bar(); // error: not a static method
C.Companion.foo(); // instance method remains
C.Companion.bar(); // the only way it works
//kotlin
object Obj {
@JvmStatic fun foo() {}
fun bar() {}
}
//java
Obj.foo(); // works fine
Obj.bar(); // error
Obj.INSTANCE.bar(); // works, a call through the singleton instance
Obj.INSTANCE.foo(); // works too
6.可見域
- kotlin的private成員函數變成java的private成員函數
- kotlin的private頂級聲明(直接在kotlin文件下面)變成java的包可見聲明
- kotlin的protected在Java還是一樣,但是需要注意的是Java的protected可以訪問同一個包下面的所有,但是kotlin是private+子類可見,所以明顯Java的protected可見域比kotlin要大
- kotlin的internal變成java的public
- kotlin的public變成Java的public
7.KClass
有些時候需要從KClass類型中獲取Kotlin方法,但是Class不等於KClass,所以你需要如下
kotlin.jvm.JvmClassMappingKt.getKotlinClass(MainView.class)
8.使用@JvmName處理簽名衝突
比如下面
fun List<String>.filterValid(): List<String>
fun List<Int>.filterValid(): List<Int>
上面兩個在Jvm的簽名都是一樣的:filterValid(Ljava/util/List;)Ljava/util/List;
所以需要區分,使用@JvmName
fun List<String>.filterValid(): List<String>
@JvmName("filterValidInt")
fun List<Int>.filterValid(): List<Int>
//在Java中調用
filterValid
filterValidInt
一個同樣的例子
val x: Int
@JvmName("getX_prop")
get() = 15
fun getX() = 10
9.生成覆載方法
比如,有kotlin代碼
fun f(a: String, b: Int = 0, c: String = "abc") {
...
}
//調用
f(a)
f(a, b)
f(a, b, c)
要想在Java也這樣調用,所以對方法加上@JvmOverloads
@JvmOverloads fun f(a: String, b: Int = 0, c: String = "abc") {
...
}
// Java,自動生成的
void f(String a, int b, String c) { }
void f(String a, int b) { }
void f(String a) { }
10.檢查異常
比如有kotlin代碼
// example.kt
package demo
fun foo() {
throw IOException()
}
//我們希望在java如下調用
// Java
try {
demo.Example.foo();
}
catch (IOException e) { // error: foo() does not declare IOException in the throws list
// ...
}
需要如下添加@Throws註釋,如下
@Throws(IOException::class)
fun foo() {
throw IOException()
}
11.Null安全
不保證
12.變體泛型
如下kotlin代碼
class Box<out T>(val value: T)
interface Base
class Derived : Base
fun boxDerived(value: Derived): Box<Derived> = Box(value)
fun unboxBase(box: Box<Base>): Base = box.value
//可以天真的用下面的Java代碼代替
Box<Derived> boxDerived(Derived value) { ... }
Base unboxBase(Box<Base> box) { ... }
//但是有個問題,
unboxBase(boxDerived("s")) 這行代碼可以在kotlin沒問題,因爲Box<Derived>是Box<Base>的子類型(注意out修飾了泛型),但是在Java,我們知道肯定報錯的。所以
Base unboxBase(Box<Base> box) { ... }//ERROR,要改成如下
Base unboxBase(Box<? extends Base> box) { ... } //這樣就可以使用unboxBase(boxDerived("s"))
13.Nothing的轉化
//kotlin
fun emptyList(): List<Nothing> = listOf()
// is translated to Java
List emptyList() { ... }