在底层,像 Int 这样的 Kotlin 类型,会编译成 Java 对应的基本数据类型,因为两者都不能存储 null 值。
反过来也一样,Java 的基本数据类型会被当做非空类型(而不是平台类型),因为他们都不能有 null 值。
在底层,像 Int? 这样的可空 Kotlin 类型,会被编译成 Java 基本数据类型的不能用 Java 的基本数据类型来表示,因为它可能是 null。
另外,在使用泛型的时候,Java 和 Kotlin 都不支持使用基本数据类型做类型参数,所以泛型类都必须使用类型的包装表示。
Kotlin 不会自动地把数字从一种类型转化为另外一种,即便是转换成范围更大的类型。
数字转换必须是显式的,即通过转换函数 toByte()、toShort()、toChar() 等。因为 kotlin 的基本数据类型就是 java 的包装类型,而包装类型的比较不仅要比较值,还要比较类型。只有类型相同才能比较。
val a = 1 val b: Long = a.toLong() a == b // 报错,Operator '==' cannot be applied to 'Int' and 'Long' a.equals(b) // false Integer a = 1; Long b = Long.valueOf(a); a == b // 报错,Operator '==' cannot be applied to 'java.lang.Integer' and 'java.lang.Long' a.equals(b) // false相当于作为 Java 中的 Object,Any 类型是 Kotlin 所有非空类型的根。
Any? 是 Any 的可空类型。
Any 在底层会被编译为 java.lang.Object,所有 Kotlin 类都可以使用Any(即 Object)的三个方法:toString、equals 和 hashCode。但不能使用 Object 的其他方法(如 wait 和 notify),但可以手动将 Any 转为 Object 来调用。
val a = ("hello" as java.lang.Object).wait()当函数没什么结果要返回时,它可以用做函数的返回类型:
fun f(): Unit {...} // Unit 可以省略 fun f(): {...}Unit 与 void 的区别:Unit 是一个完备的类型,可以作为类型参数,void 不行。
Unit 类型的值只有一个,也叫作 Unit。并且在函数中会被隐式地返回。
使用 Unit 作为返回值的好处是,可以把 java 中的有返回值的函数和无返回值的函数统一,都变成有返回值的函数。这在使用泛型函数时很有帮助。
interface Processor<T> { fun process(): T } class AProcessor : Processor<Unit> { override fun process() { println("process A") } } class BProcessor : Processor<Int> { override fun process(): Int { return 1 } }在 java 中,要实现这样的功能,要么写两个接口,要么就使用 Void 类,使用 Void 类就要手动 return null,没有 kotlin 方便。
kotlin 中的 Void 就是 java 中的 Void,表示一个不可实例化的占位符。
Nothing 没有任何值,只有当作函数返回值时才有意义,表示这个函数不会返回(如抛出异常或无限循环)。
fun fail(message: String): Nothing { throw Exception(message) } val address = company.address ?: fail("No address") println(address.city)像上面的 fail 函数,就永远不会返回。在调用的时候,如果进行到了下一步,那就说明 company.address 不为空,不用再进行判断,Kotlin 会自动进行转换。