基本数据类型和其他基本类型
基本数据类型:Int、Boolean 及其他
Kotlin 并不区分基本数据类型和包装类型,你使用的永远是同一个类型。在运行时,数字类型会尽可能地使用最高效的方式来表示。Int 类型会被编译成 Java 基本数据类型 int。不可行的例外是泛型类,比如集合。用作泛型类型参数的基本数据类型会被编译成对应的 Java 包装类型。
整数类型
- Byte: 8 位有符号整数
- Short: 16 位有符号整数
- Int: 32 位有符号整数(默认)
- Long: 64 位有符号整数
浮点数类型
- Float: 32 位单精度浮点数
- Double: 64 位双精度浮点数(默认)
字符类型
- Char: 16 位 Unicode 字符
布尔类型
- Boolean: true 或 false
可空的基本数据类型:Int?、Boolean?及其他
Kotlin 中的可空类型不能用 Java 的基本数据类型表示,因为 null 只能被存储在 Java 的引用类型的变量中。只要使用了基本类型的可空版本,它就会被编译成对应的包装类型。JVM 不支持用基本数据类型作为类型参数,所以泛型类必须始终使用类型的包装表示。
例如:List<Int?> 表示一个包含可空整数的列表,而 List<Int> 表示一个不包含 null 的整数列表。
数字转换
Kotlin 不会自动地把数字从一种类型转换成另一种类型,必须进行显式转换。每一种基本数据类型(Boolean 除外)都定义有转换函数:toByte()、toShort()、toInt()、toLong()、toFloat()、toDouble()、toChar()。这些函数支持双向转换。
为了避免意外情况,Kotlin 要求转换必须是显式的,尤其是在比较装箱值的时候。比较两个装箱值的 equals 方法不仅会检查它们存储的值,还要比较装箱类型。在 Java 中 new Integer(42).equals(new Long(42)) 会返回 false,而在 Kotlin 中由于类型系统的严格性,这种混淆更容易被避免。
基本数据类型字面值
Kotlin 支持以下这些在代码中书写数字字面值的方式:
- 使用后缀 L 表示 Long 类型 (长整型) 字面值:123L
- 使用标准浮点数表示 Double(双精度浮点数) 字面值:0.12、2.0、1.2e10
- 使用后缀 F 表示 Float 类型 (浮点数) 字面值:123.4f、456F
- 使用前缀 0x 或者 0X 表示十六进制字面值:0x123
- 使用前缀 0b 或者 0B 表示二进制字面值:0b0101
当你书写数字字面值的时候一般不需要使用转换函数,即使你没有用上面的这些语法,当你使用数字字面值去初始化一个类型已知的变量时,又或是把字面值作为实参传给函数时,必要的转换会自动发生。此外算术运算符也被重载了,它们可以接收所有适当的数字类型。
Any 和 Any?:根类型
Any 是 Kotlin 所有非空类型的超类型。但在 Java 中,Object 只是所有引用类型的超类型,而基本数据类型并不是类层级结构的一部分。和 Java 一样,把基本数据类型的值赋给 Any 类型的变量时会自动装箱。Any 是非空类型,所以 Any 类型的变量不能持有 null 值。在 Kotlin 中如果你要持有任何可能值的变量,包括 null 就要使用 Any? 类型。在底层 Any 类型对应 Object。所有 Kotlin 类都包含 toString、equals、hashCode,这些方法都继承自 Any。但 Any 不能使用其他 Object 的方法,比如 wait 和 notify,但可以通过手动把值转换成 Object 来调用。
val anyValue: Any = 1
val nullableAny: Any? = null
println(anyValue.toString()) // 输出 "1"


