Skip to content

基础数据类型

众所周知,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