Kotlin官方一直以100% interoperable with Java™作为第一要素,他不是像Scala一样把类库都自己实现一遍,而是通过扩展函数、函数编程等特性对现有的Java进行增强,同时保持对Java的100%兼容。正是这个特性,我们可以在一个项目中同时使用Java和Kotlin,一个大型的项目,如果换一种语言来实现的话,这个代价是非常大的。但是对于一个Java项目,你可以某一部分使用Kotlin来实现,然后慢慢地一步步的把整个项目所有代码都改成Kotlin实现。这样风险就会小非常多。
1. Kotlin调用Java
1.1 Kotlin使用Java的集合类
val kotlinList = listOf(1, 2, 3, 4)
//Java原生的ArrayList
val javaList = ArrayList()
for (item in kotlinList) {
javaList.add(item)
}
操作Java原生的集合类跟Kotlin中使用类没有什么区别。
1.2 调用Java类的getter和setter
假如我们有这样一个Person类。
package com.dengyin2000.java;
public class Person {
private String name;
private Long id;
private boolean isFemale;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isFemale() {
return isFemale;
}
public void setFemale(boolean female) {
isFemale = female;
}
}
那么在Kotlin中要怎样使用呢?
val person = Person()
person.id = 1
person.name = "Denny"
person.isFemale = false
println("Person(id=${person.id}, name=${person.name}, isFemale=${person.isFemale})")
println函数中的person类调用的是Person类的getter,上面属性设置实际上调用的是Person类的setter方法。
1.3 空安全
Java声明的类型在Kotlin中会被特别对待并称为平台类型(platform types),对于这种类型的空检查会放宽,这样做就使得跟Java的调用方式一致,但是Java中的任何引用都可能为null,这样我们使用Kotlin调用来自Java的对象的时候就有可能会出现空安全的问题。例如:
val person = Person()
person.id = 1
person.isFemale = false
println(person.name.substring(1))
person.name运行时为null,当然调用的时候会person.name.substring(1)时会发生异常。
异常
当然为了避免null的问题,我们可以使用Koltin的安全调用:
println(person.name?.substring(1)) //打印null
1.4 平台类型
平台类型不能在程序中显式表述,因此在语言中没有相应语法。 然而,编译器和 IDE 有时需要(在错误信息中、参数信息中等)显示他们,所以我们用一个助记符来表示他们:
T! : 表示 T 或者 T?
(Mutable) Collection! : 表示 “可以可变或不可变、可空或不可空的 T 的 Java 集合”
Array! : 表示“可空或者不可空的 T(或 T 的子类型)的 Java 数组”
1.5 Kotlin与Java中的类型映射
Kotlin 特殊处理一部分 Java 类型。这样的类型不是“按原样”从 Java 加载,而是 映射 到相应的 Kotlin 类型。 映射只发生在编译期间,运行时表示保持不变。怎么理解这句话呢?就是说在Kotlin中加载这些Java的类型时,编译器会转成对应的Kotlin类型,这样就能用到Koltin中对Java的增强功能(扩展函数等)。
1.5.1 Java的原生类型映射到对应的Kotlin类型
Java的原生类型映射到对应的Kotlin类型
1.5.2 Java中的一些内置类型也会做相应的映射
Java中的一些内置类型也会做相应的映射
1.5.3 Java的基本类型的包装类对应到可空额Kotlin类型
Java的基本类型的包装类对应到可空额Kotlin类型
1.5.4 类型参数的Java类型映射到Kotlin中的平台类型
例如:List 在Kotlin会变成List
集合类型在 Kotlin 中可以是只读的或可变的,因此 Java 集合类型作如下映射: (下表中的所有 Kotlin 类型都在 kotlin.collections包中):
类型参数的Java类型映射到Kotlin中的平台类型
1.5.5 Java的数组映射
Java的数组映射
1.6 Kotlin中使用Java泛型
Kotlin 的泛型与 Java 有点不同。当将 Java 类型导入 Kotlin 时,我们会执行一些转换: