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() { ... }