Kotlin与Java互操作

2023-06-14,,

1,Kotlin 调用Java

import java.util.*

fun demo(source: List<Int>) {
    val list = ArrayList<Int>()    
    for (item in source) {
        list.add(item)
    }
    for (i in 0..source.size - 1) {
        list[i] = source[i] // get and set are called
    }
}

关于getter和setter的默认调用

import java.util.Calendar

fun calendarDemo() {
    val calendar = Calendar.getInstance()
    if (calendar.firstDayOfWeek == Calendar.SUNDAY) {  // 调用了getFirstDayOfWeek()
        calendar.firstDayOfWeek = Calendar.MONDAY      // 调用了 setFirstDayOfWeek()
    }
    if (!calendar.isLenient) {                         // 调用了isLenient()
        calendar.isLenient = true                      // 调用了setLenient()
    }
}

注意,如果一个java属性只有setter,那么Kotlin就无法访问。 Kotlin访问java的属性其实是默认调用了这个属性的getter函数

如果一个java函数是void类型的,那么kotlin调用后获得的返回值类型是Unit

如果一个java函数名用了kotlin的关键字,比如inobjectis ,那么在kotlin中访问的时候,要给函数名加上' ,

foo.`is`(bar)

2,null安全和平台类型

java中的对象很可能是null,kotlin把java对象当做平台类型,对其null安全要求不再那么苛刻

val list = ArrayList<String>() // 不需要java的new了
list.add("Item")
val size = list.size 
val item = list[0] // 普通java对象,当做平台类型
//当我们调用平台类型的变量时, Kotlin不会在编译阶段就做null安全性检查, 但运行的时候可能会访问失败
item.substring(1) // 编译通过,运行的时候如果item是null就会抛出exception 
val nullable: String? = item // 正确
val notNull: String = item // 编译通过,但运行时可能报错

我们不能在代码中显式声明平台类型,为了方便编译阶段检查,我们设定以下记忆符号:

  • T! 意思是 "T 或T?",

  • (Mutable)Collection<T>! 意思是 "Java collection of T may be mutable or not, may be nullable or not",

  • Array<(out) T>! 意思是"Java array of T (or a subtype of T), nullable or not"

3,类型对应关系

Java type Kotlin type
byte kotlin.Byte
short kotlin.Short
int kotlin.Int
long kotlin.Long
char kotlin.Char
float kotlin.Float
double kotlin.Double
boolean kotlin.Boolean

 

Java type Kotlin type
java.lang.Object kotlin.Any!
java.lang.Cloneable kotlin.Cloneable!
java.lang.Comparable kotlin.Comparable!
java.lang.Enum kotlin.Enum!
java.lang.Annotation kotlin.Annotation!
java.lang.Deprecated kotlin.Deprecated!
java.lang.CharSequence kotlin.CharSequence!
java.lang.String kotlin.String!
java.lang.Number kotlin.Number!
java.lang.Throwable kotlin.Throwable!

 

Edit Page


Java type Kotlin type
java.lang.Byte kotlin.Byte?
java.lang.Short kotlin.Short?
java.lang.Integer kotlin.Int?
java.lang.Long kotlin.Long?
java.lang.Character kotlin.Char?
java.lang.Float kotlin.Float?
java.lang.Double kotlin.Double?
java.lang.Boolean kotlin.Boolean?

注意,如果java用了原始类型为参数,那么在kotlin中转换为平台类型,比如:List<java.lang.Integer> 在kotlin中对应 List<Int!> 

Kotlin的集合类型可以是只读的,或者可变的,所以,跟java的集合类型对应关系如下  (下表里面的这些Kotlin 类型都在包 kotlin.collections里):

Java type Kotlin read-only type Kotlin mutable type Loaded platform type
Iterator<T> Iterator<T> MutableIterator<T> (Mutable)Iterator<T>!
Iterable<T> Iterable<T> MutableIterable<T> (Mutable)Iterable<T>!
Collection<T> Collection<T> MutableCollection<T> (Mutable)Collection<T>!
Set<T> Set<T> MutableSet<T> (Mutable)Set<T>!
List<T> List<T> MutableList<T> (Mutable)List<T>!
ListIterator<T> ListIterator<T> MutableListIterator<T> (Mutable)ListIterator<T>!
Map<K, V> Map<K, V> MutableMap<K, V> (Mutable)Map<K, V>!
Map.Entry<K, V> Map.Entry<K, V> MutableMap.MutableEntry<K,V> (Mutable)Map.(Mutable)Entry<K, V>!

Java'的对应如下:

Java type Kotlin type
int[] kotlin.IntArray!
String[] kotlin.Array<(out) String>!

注意: java的static 变量不能作为kotlin companion 对象直接访问,必须要带上java类型才可以,比如 java.lang.Integer.toHexString(foo).

参考文献:https://kotlinlang.org/docs/reference/java-interop.html



《Kotlin与Java互操作.doc》

下载本文的Word格式文档,以方便收藏与打印。