基础数据类型
众所周知,Java把数据类型分为了基本数据类型和引用类型,基本数据类型的变量直接存储了它的值在栈上分配;而引用类型的变量在堆上分配,持有对象地址的引用. Java还对基础数据类型进行了包装, 比如: Integer
Long
Kotlin并不区分基础数据类型和包装类型,使用的都是同一对象,比如 Int
; 由于Kotlin代码最终会编译成Java,若都编译成包装类型那效率会很低效,所以在编译的时候Kotlin尽量将类型 Int 编译成基础数据类型 int; 唯一例外是泛型类
基础数据类型:
- 整数类型 Byte、Int、Long、Short
- 浮点类型 Float、Double
- 字符类型 Char
- 布尔类型 Boolean
在java中基础数据类型不能存储null值, 所以在Koltin中如果使用了可空的数据类型定义,比如:Int?
, 他就会被编译成对应的包装类型
数字类型转换
Kotlin不会自动把数字从一种类型转换成另一种类型,即使是转换成范围更大的类型, 例如:
var i: Int = 1
var z: Long = i
这段代码编译时会报错, 必须调用i.toLong()
显示的转换成Long
当书写数字的字面值的时候,不用显示调用转换,程序依然能够正常运行, 是由于Kotlin能够推断出类型, 比如:
val list = listOf(1L, 2L)
print(1 in list)
这段代码能够正常执行, 由于in
关键字实际调用的是list.contains
, 这个方法的参数已经确定是Long
Any
Any和java中Object差不多,是所有非空类型的根类, 如果把基础数据类型值赋值给Any对象,那么变量会自动装箱
var x: Any = 1
当你需要Any变量持有null值的时候,需要使用Any?
Unit
Unit类型的功能与Java中void的功能一样,当函数没有返回值的时候可以使用Unit
, 当然也可以不用写. 下面来看一个Unit的使用场景
interface Processor<T> {
fun process(): T
}
class DefaultProcessor : Processor<Unit>{
override fun process() {
}
}
DefaultProcessor 指定了泛型为Unit, 所以在实现process方法的时候不需要再写return
集合可空性
在使用集合的时候,可以控制集合中的元素是否允许为空,比如:ArrayList<Int?>
, 当然也可以控制整个集合对象是否允许为空
var list: List<Int?>?
- 第一种情况: 集合本身不能为null, 但是其中的元素可能是null
- 第二种情况: 集合本身可能是null, 其中的元素不能为null
集合提供了函数filterNotNull
来过滤掉集合中的空值
val list = listOf(1L, 2L, null)
print(list.filterNotNull())
只读集合与可变集合
Kotlin集合设计与Java有点不同,它把集合接口分为了只读与可变.
- 只读接口可以遍历,查询集合大小,判断是否包含某个元素等等,接口:
kotlin.collections.Collection
- 可变接口可以修改集合中的数据,添加元素,删除元素,清空集合等等,接口:
kotlin.collections.MutableCollection
只读与可变接口的分离能够让程序更加清晰,比如方法的参数是只读接口,那么说明这个方法中只能读取集合不能修改集合
数组
Kotlin中创建数组的三种方式:
- arrayOf 函数的参数为该数组的元素
arrayOf(1, 2, 3)
- arrayOfNulls 创建一个指定大小的数组,包含了null元素
arrayOfNulls<Int>(3)
- Array 构造方法接受数组的大小和一个lambda表达式, lambda表达式的参数是数组的大小
Array(3) { it + 1 }
数组类型的类型参数始终都会编译成对象类型, 即使数组的元素是基础数据类型也会被编译包装类型的数组; 如果需要使用没有包装类型的数组,需要使用Kotlin提供的特殊类,比如:IntArray
CharArray
BooleanArray
创建一个int基础数据类型的数组
- IntArray的构造方法, 参数数组的大小和初始化元素的lambda表达式
- intArrayOf方法, 参数数组的大小
如果拥有一个持有基础数据类型的装箱类数组,可以把它转换成基础数据类型数组 比如: arrayOf(1, 3).toIntArray()
遍历数组可以使用 forEachIndexed
arrayOf(1, 3).forEachIndexed { i, element ->
println("index: $i, element: $element")
}
原文链接: http://herman7z.site