与Java类似,Kotlin也提供了4种整型。
- Byte:Byte型整数在内存里通常占8位,表数范围是:-128~127。兼容Java的byte和Byte类型。
- Short:Short型整数在内存里占16位,表数范围是:-32768(-215)~32767(215-1)。兼容Java的short和Short类型。
- Int:Int型整数在内存里占32位,表数范围是:-2147483648(-231)~-2147483647(231-1)。兼容Java的int和Integer类型。
- Long:Long型整数在内存里占64位,表数范围是:-263~263-1。兼容Java的long和Long类型。
当程序直接给出一个较大的整数时,该整数默认可能就是Long型,如果将这个整数赋值给Int、Short或Byte型,编译器将会报错。
例如如下代码。
程序清单:codes\02\2.3\IntVarTest.kt
fun main(args: Array<String>) {
// 下面代码是正确的
var a:Int = 56
// 下面代码需要隐式地将2999999999转换为Int型使用,因此编译器将会报错
var bigValue : Int = 2999999999
// 下面代码是正确的
var bigValue2: Long = 2999999999
println(bigValue)
println(bigValue2)
println(Short.MIN_VALUE)
println(Short.MAX_VALUE)
}
上面程序中粗体字代码将2999999999作为Int型变量的初始值,但2999999999的值处于Long的取值范围内,因此2999999999将被当成Long型使用。故而上面这条粗体字代码报错。
提示:一般来说,开发者应该尽量使用Int型就足够了,这样可以提高代码的一致性和可复用性。
由于Int型是Kotlin最常用的整数类型,因此,如果声明一个常量或变量时没有指定数据类型,只是简单地指定了其初始值为整数值,那么Kotlin会自动判断该变量的类型为Int。
Kotlin的整型与Java的整型不同,Kotlin的整型不是基本类型,而是引用类型(大致相当于Java的包装类),Byte、Short、Int、Long都继承了Number类型,因此这些Byte、Short、Int、Long都可调用方法、访问属性。
程序可通过访问不同整数类型的MIN_VALUE和MAX_VALUE属性来获取对应类型的最大值和最小值。例如如下代码(程序清单同上):
println(Short.MIN_VALUE)
println(Short.MAX_VALUE)
有一点需要提前说明的是:Kotlin是null安全的语言,因此Byte、Short、Int、Long型变量都能不接受null值,如果要存储null值,应该使用Byte?、Short?、Int?、Long?类型。例如如下代码(程序清单同上):
// Int型变量不支持null值,所以下面代码是错误的
var notNull: Int = null
// Int?相当于支持null值的Int型,所以下面代码是正确的
var nullable: Int? = null
由此可见,Kotlin语言允许在已有数据类型后添加?,添加?后的数据类型相当于对原有类型进行了扩展,带?的数据类型可支持被赋值null值。
此外,整型类型添加?后缀与不加后缀还有一个区别:普通类型的整型变量,将会映射成Java的基本类型;带?后缀的的整型变量,将会映射成基本类型的包装类。举例来说,Kotlin程序中Int类型的变量将会映射成Java的int基本类型,但Int?类型的变量则会自动映射成Java的Integer类型。例如如下代码(程序清单同上):
var pm1: Int = 200; // pm1的类型是Java的int类型
var pm2: Int = 200; // pm2的类型是Java的int类型
println(pm1 === pm2); // 基本类型比较,输出true
var ob1: Int? = 200; // ob1的类型是Java的Integer类型
var ob2: Int? = 200; // ob2的类型是Java的Integer类型
println(ob1 === ob2); // 引用类型比较,输出false
上面代码中由于pm1、pm2两个变量都映射成Java的基本类型,因此即使用===比较相等(该元算赋要求两个变量引用同一个对象)也返回true;但ob1、ob2两个变量都映射成Java的Integer对象,此时用ob1和ob2不再引用同一个对象,因此它们用===比较返回false。
注意:如果将ob1、ob2的值改为小于-128~127之间的整数,上面ob1和ob2用===比较依然是相等的,这是由于Java的Integer类的特征决定,关于这一点可参考《疯狂Java讲义》6.2节。
Kotlin的整数数值有3种表示方式。
- 十进制:最普通的整数就是十进制的整数。
- 二进制:以0b或0B开头的整数就是二进制的整数。
- 十六进制:以0x或0X开头的整数就是十六进制的整数,其中10~15分别以a~f(此处的a~f不区分大小写)来表示。
注意:Kotlin不支持八进制整数。
下面代码片段分别使用了二进制、十六进制的数。
程序清单:codes\02\2.3\HexTest.kt
fun main(args: Array<String>) {
// 以0b或0B开头的整数数值是二进制的整数
var binValue1 = 0b1010101
var binValue2 = 0B10101110
// 以0x或0X开头的整数数值是十六进制的整数
var hexValue1 = 0x13
var hexValue2 = 0XaF
println("binValue1的值为:${binValue1}")
println("binValue2的值为:${binValue2}")
println("hexValue1的值为:${hexValue1}")
println("hexValue2的值为:${hexValue2}")
}
上面代码中用到了字符串模板:也就是在字符串中嵌入${}的形式,该${}内可放入变量或表达式,Kotlin会将该变量或表达式的值“嵌入”该字符串内。
为了提高数值(包括浮点型)的可读性,Kotlin允许为数值(包括浮点型)增加下画线作为分隔符,也可以在数值前添加额外的零。这些下画线和零并不会影响数值本身。例如如下代码(程序清单同上):
val oneMillion = 1_000_000
val price = 234_234_234 // price实际的值为234234234
val android = 1234_1234 // android实际的值为12341234