文章目录
一、基本数据类型:Int、Boolean 及其他
- 整数类型——Byte、Short、Int、Long
- 浮点数类型——Flost、Double
- 字符类型——Char
- 布尔类型——Boolean
在底层,像 Int 这样的 Kotlin 类型,会编译成 Java 对应的基本数据类型,因为两者都不能存储 null 值。
反过来也一样,Java 的基本数据类型会被当做非空类型(而不是平台类型),因为他们都不能有 null 值。
二、可空的基本数据类型:Int?、Boolean 及其他
在底层,像 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
四、“Any” 和 “Any?”:根类型
相当于作为 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()
五、Unit 类型:Kotlin 的 “void”
当函数没什么结果要返回时,它可以用做函数的返回类型:
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:“这个函数永不返回”
Nothing 没有任何值,只有当作函数返回值时才有意义,表示这个函数不会返回(如抛出异常或无限循环)。
fun fail(message: String): Nothing {
throw Exception(message)
}
val address = company.address ?: fail("No address")
println(address.city)
像上面的 fail 函数,就永远不会返回。在调用的时候,如果进行到了下一步,那就说明 company.address 不为空,不用再进行判断,Kotlin 会自动进行转换。