06-数值类型
4.3.1 数值类型
Kotlin的基本数值类型包括Byte、Short、Int、Long、Float和Double等。不同于Java,在Kotlin中字符(Charactor)不属于数值类型。表4-1列出了基本数值类型及其位宽度。
| 数据类型 | 位宽度 | 数据类型 | 位宽度 | | :----- | :----- | :----- | :----- | :----- | :----- | | Double | 64 | Int | 32 | | Long | 64 | Short | 16 | | Float | 32 | Byte | 8 |
1.数值常量
Kotlin的数值常量定义和Java类似,如表4-2所示。
| 常量类型 | 示例 | | :----- | :----- | :----- | :----- | | 十进制 | 123,Long 类型用大写L标记,如123L | | 十六进制 | 0x0F | | 二进制 | 0b00001011 | | 浮点数 | Float用f或者F标记,如123F |
为了使程序的可读性更强,从1.1版本开始,Kotlin允许使用下划线来对数字常量进行分组。
val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
在Java平台上,数字都是以JVM的原始类型进行存储的,只有涉及可空的数字引用或者泛型时,才会引起数字的装箱操作。Kotlin将系统类型分为可空类型和不可空类型,对于数字类型而言,不可空类型类似于Java的基本数字类型。
al a: Int = 1000
val b: Int = 1000
println(a==b) //true
println(a===b) //true
上面的返回结果都是true,因为a和b都是以原始类型进行存储的,类似于Java的基本数字类型。
val a: Int? = 1000
val b: Int? = 1000
println(a==b) //true
println(a===b) //false
在Kotlin中,“===”表示恒等于,“==”表示等于,这和JavaScript的语法规则是一样的。在理解它们的关系时,需注意以下几点。
- ==:表示等于运算,比较的是值,而不是引用。
- ===:表示完全等于运算,不仅比较值,而且还比较引用。
上面的代码中,a和b都进行了装箱操作,因此它们是不同的引用,但是它们引用的值是相等的。
2.显式转换
由于不同包装类的存在,因此较小的类型并不是较大类型的子类型,在比较不同包装类型的时候可能会遇到以下的情况。
val a: Int? = 1 //Int装箱 (java.lang.Integer)
val b: Long? = a //隐式转换生成Long装箱类型 (java.lang.Long)
print(a == b) //返回 "false",因为Long只能和Long比较
其实,上面的代码是不能通过编译的,之所以会报错,是因为较小的数字类型不能隐式转换为较大的数字类型。这意味着我们不能隐式地把Byte类型的值赋给Int类型的变量,除非通过显式的方式转换。
al b: Byte = 1 //正确, 字面常量被静态检查
val i: Int = b //错误
val i: Int = b.toInt() //正确,通过显式转换提升精度
但是,两个不同类型的数字在进行逻辑运算时并不需要特别注意,算术运算符会重载以适应不同类型的转换。代码如下。
val l = 1L + 3 // Long + Int => Long
数字对于每一个数字类型都支持如表4-3所示的显式转换。
| 类型 | 支持的显式转换 | 类型 | 支持的显式转换 | | :----- | :----- | :----- | :----- | :----- | :----- | | Byte | toByte() | Float | toFloat() | | Short | toShort() | Double | toDouble() | | Int | toInt() | Char | toChar() | | Long | toLong() |
3.运算符
Kotlin支持标准的算术运算符,这些运算符被定义为相应的类成员变量。具体使用过程中,编译器会将函数调用优化为相应的指令。对于位运算来说,没有特殊的字符来表示,只能用中缀方式调用命名函数。代码如下。
val x = (1 shl 2) and 0x000FF000