第21章 Kotlin与Java混合编程
Kotlin毕竟还是一种新的语言,所以很多项目、组件和框架还是用Java开发的,目前Kotlin不能完全取代Java,因此有时会使用Kotlin调用Java写好的组件或框架。Kotlin在设计之初充分地考虑了与Java的混合编程。本章介绍Kotlin与Java混合编程。
21.1 数据类型映射
Kotlin虽然最终会编译为字节码在Java虚拟机上运行,它的一些数据类型会编译为Java中的数据类型。Kotlin中的一些数据类型与Java的一些数据类型有一定的映射关系的,主要分为Java基本数据类型、Java包装类、Java常用类和Java集合类型几个方面。
21.1.1 Java基本数据类型与Kotlin数据类型映射
Java基本数据类型与Kotlin数据类型映射如表21-1所示,其中Kotlin这些数据类型都是基本数据类型,位于kotlin包中。
21.1.2 Java包装类与Kotlin数据类型映射
Java包装类是对Java基本数据类型的包装,Java包装类可以有空值,所以映射到Kotlin数据类型时是可空类型,如表21-2所示。
21.1.3 Java常用类与Kotlin数据类型映射
Java常用类是位于java.lang中一些核心类,它们映射到Kotlin数据类型时是非空或可空类型,如表21-3所示。
21.1.4 Java集合类型与Kotlin数据类型映射
Java集合类型是映射到Kotlin数据类型如表21-4所示。从表21-4可见Java的集合不区分可变和不可变,而Kotlin中有这样的区别,在表21-4中还有一种平台类型,在混合编程时Kotlin将它们看作可空或非空,所以平台类型(Mutable)Iterator!表示的是Iterator、Iterator?、MutableIterator和MutableIterator?四种可能性。
21.2 Kotlin调用Java
混合编程包含了两个方面:Kotlin调用Java和Java调用Kotlin。本节先介绍Kotlin调用Java,事实上Kotlin调用Java非常简单,因为Kotlin是主动的,Java是被动的,Kotlin在设计之初充分地考虑到Kotlin主动调用Java各种情况。
下面从几个方面分别介绍一下。
21.2.1 避免Kotlin关键字
或许Java程序员在给Java标识符命名是时并没有考虑到哪些Kotlin的关键字。但当Kotlin中调用这样的Java代码时,则需要将这些关键字用反引号括起来。例如Java标准输入流System.in,如果在Kotlin中调用则需要表示为System.in
。
示例Java代码如下:
//Java代码文件:chapter21/src/main/java/com/a51work6/section2/MyJavaClass.java
package com.a51work6.section2;
public class MyJavaClass {
public static MyJavaClass object =new MyJavaClass(); ①
@Override
public String toString() {
return "MyJavaClass{}";
}
}
调用的Kotlin代码如下:
//Kotlin代码文件:chapter21/src/main/kotlin/com/a51work6/section2/ch21.2.1.kt
package com.a51work6.section2
fun main(args: Array) {
val obj = MyJavaClass.object
②
println(obj)
}
在Java代码中使用object命名变量,见代码第①行。那么在Kotlin中调用它时需要使用反引号括起来,见代码第②行。
21.2.2 平台类型与空值
在21.1节介绍类型映射时介绍过程平台类型,这些类型在Java中声明了一个变量或返回的数据可能为空,也可能非空。Kotlin在调用它们时会放弃类型检查。
示例代码如下:
//Java代码文件:chapter21/src/main/java/com/a51work6/section2/Person.java
package com.a51work6.section2;
import java.util.Date;
public class Person {
// 名字
private String name =“Tony”;
// 年龄
private int age = 18;
// 出生日期
private Date birthDate; ①
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//Kotlin代码文件:chapter21/src/main/kotlin/com/a51work6/section2/ch21.2.2.kt
package com.a51work6.section2
import java.util.*
fun main(args: Array) {
val person = Person()
val date = person.birthDate ②
println(“date = $date”) //null
val date1: Date? = person.birthDate ③
println(“date1 = $date1”) //null
val date2: Date = person.birthDate //抛出异常 ④
println(“date2 = $date2”)
}
上述代码编写了一个Java类Person,它的birthDate字段没有初始化所以为空值,见代码第①行。在Kotlin中通过属性访问Java中的setter或getter函数的&#