博客
关于我
Kotlin学习篇(4)—— Kotlin的类型系统
阅读量:608 次
发布时间:2019-03-12

本文共 3515 字,大约阅读时间需要 11 分钟。

Kotlin的类型系统:可空性解析

Kotlin的类型系统虽然与Java有截然不同的默认处理方式,但在某些方面也为我们提供了更多的灵活性和安全机制。其中,可空性(Nullable Types)是Kotlin中非常值得关注的一个特性。以下将详细解释可空性在Kotlin中的使用及其相关功能。

5.1 可空类型

在Kotlin中,可空性通过在类型名后面添加问号(?)来表示。例如,String变量可以声明为String?,表明它可以存储null引用。这种设计与传统Java的可空性思想有很大不同,因为Kotlin默认所有类型均为非空类型。

5.1.1 可空类型的使用限制

使用可空类型会带来一些限制:

  • 方法调用:不能在可空类型上直接调用那些期望非空类型参数的方法。例如,调用s.length,其中s是String?,会在s为null时抛出NullPointerException。
  • 赋值:不能将可空类型赋给非空类型变量。例如,将String?赋给String是不允许的。
  • 函数传递:不能将可空类型的值传递给那些期望非空类型参数的函数,否则也会抛出异常。

5.1.2 安全调用运算符

为了处理这些限制,Kotlin提供了多种安全调用运算符:

  • ?.运算符:这是最常见的安全运算符,能够在调用方法前进行一次null检查。例如,s?.length。当s为null时,返回null,不会抛出异常。
  • ?::运算符:用于对可空属性进行安全调用。例如,person?.age。
  • !!运算符:非空断言运算符。它断言变量是非空的。如果变量为null,会抛出NullPointerException。例如,!!null会抛出NullPointerException。
  • let函数:将可空对象的非null值转换为lambda表达式的参数。例如,x?.let { ... },如果x为空,函数不会执行。

5.1.3 延迟初始化的属性

Kotlin允许使用lateinit修饰符来表示延迟初始化。这种属性可以在不直接初始化的情况下使用。例如:

class MyService {    fun performAction(): String = "foo"}class MyTest {    private lateinit var myService: MyService    fun setUp() {        myService = MyService()    }    fun testAction() {        println(myService.performAction())    }}

延迟初始化的属性必须在初始化前正确配置,否则会抛出UninitializedPropertyAccessException

5.1.4 可空类型的扩展

为了更方便地处理可空类型,Kotlin允许为类和对象定义扩展函数:

  • isEmpty:判断对象是否为空。例如,String的扩展方法isEmpty可以用来判断字符串是否为空。
  • isBlank:判断字符串是否为空或仅由空白字符组成。
  • isNullOrEmpty:类似于isEmptyisBlank,但通常用于集合或序列为空检查。
  • isNullOrBlank:结合了isNullisBlank的检查功能。

5.1.5 可空性与泛型

Kotlin的泛型类型参数默认是可空的,这有时可能导致意外的null值传递。要排除这种情况,可以指定上界。例如:

fun printHashcode(t: T) {    println(t.hashCode())}// 正确使用方式:printHashcode(null) // 这里会抛出编译错误,因为T不能存储null

如果要明确T不能为null,可以指定上界:

fun 
printHashcode(t: T) { println(t.hashCode())}printHashcode(null) // 还是会抛出编译错误

要排除null值,可以指定上界为Nonnull:

fun 
printHashcode(t: T) { println(t.hashCode())}printHashcode(null) // 这里会直接报错,因为T不能存储null

5.1.6 可空性与 Java

Kotlin可以识别和处理多种可空性注解风格,例如:

  • @Nullable
  • @NotNull
  • @NotNullIf ...

如果Java代码中没有可空性注解,Kotlin会将其视为Platform类型(平台类型),这将导致在Kotlin代码中可能需要进行额外的处理。例如:

// Java代码中:public String getName() { return name; }

如果name在Java中可以为null,那么在Kotlin中使用时,需要正确进行null处理:

fun yellAt(person3: Person3) {    println(person3.name.toUpperCase())}

如果在Kotlin中name为null,这会抛出NullPointerException,除非进行了正确的null检查。

5.2 基本数据类型与其他数据类型

Kotlin的基本数据类型与Java的基本数据类型相似,但有一些差异:

  • 非空默认:Kotlin默认所有类型都是非空的。例如,不能将null赋值给val name: String
  • 泛型参数:当基本数据类型被用于泛型类型参数时,会自动包装为对应的包装类型。例如,在List泛型中,如果没有指定上界,会将其视为List<Nothing>
  • 可空类型:基本数据类型不能直接表示可空性,必须使用?符号。例如,String?会被编译为java.lang.String

5.2.1 简化转换

Kotlin简化了数值转换,用户可以直接使用原始类型进行操作,而无需显式进行装箱和拆箱。例如:

val b: Byte = 1val l = b + 1Lfoo(l)

这样会直接将ByteLong进行加法运算。

5.2.2 Any 和 Any?

Any类型是Kotlin中的根类型,表示所有非空类型的超类型。Any?表示可空的根类型。当使用Any类型时,可以接受任何非空类型的值。当使用Any?类型时,可以接受null和任何非空类型的值。

5.2.3 Unit 类型

在Kotlin中,Unit类似于Java中的void类型,用于表示没有有意义返回值的函数。Unit类型可以作为函数的返回类型,或作为类型参数。例如:

fun f(): Unit {}

Unit类型只有一个值——Unit本身,可以隐式地返回。

5.2.4 Nothing 类型

Nothing类型表示函数永远不会有返回值。它可以用来表示极端的情况,比如:

  • 失败函数:fun fail(message: String): Nothing { throw IllegalArgumentException(message) }
  • 无限循环函数:fun arrayRun(): Nothing { while (true) {} }

5.3 集合

Kotlin中的集合在类型系统中也非常灵活:

  • 列表类型

    • List: 表示列表中的元素都不为空。
    • List<Int>: 表示列表中的每个元素可以为空。
    • List<Int>?: 表示列表本身可以为空,且每个元素可以为空。
  • 集合接口

    • Collection 是只读的集合接口。
    • MutableCollection 是可变的集合接口,提供了修改操作的方法。
  • 数组

    • Kotlin中的数组是一个带有类型参数的类。可以使用arrayOfarrayOfNullsArray构造函数来创建数组。

5.3.1 只读集合与可变集合

Kotlin的集合接口将访问集和修改集分开:

  • Collection: 只读接口,适用于简单遍历和大小查询。
  • MutableCollection: 继承自Collection,提供了修改操作的方法。像添加、移除、清空元素等功能。

需要注意的是,只读集合并不一定是不可变的。即使一个集合是只读的,如果它被多个代码路径引用,其中一个代码路径修改它,其他代码路径可能会感知到修改。


这篇文章通过逐步解释Kotlin中的可空性、基础数据类型、集合等内容,帮助开发者更好地理解Kotlin的类型系统,从而更高效地开发Kotlin应用。

转载地址:http://fhpxz.baihongyu.com/

你可能感兴趣的文章
no session found for current thread
查看>>
No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
查看>>
NO.23 ZenTaoPHP目录结构
查看>>
no1
查看>>
NO32 网络层次及OSI7层模型--TCP三次握手四次断开--子网划分
查看>>
NOAA(美国海洋和大气管理局)气象数据获取与POI点数据获取
查看>>
NoClassDefFoundError: org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata
查看>>
node exporter完整版
查看>>
Node JS: < 一> 初识Node JS
查看>>
Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime(72)
查看>>
Node 裁切图片的方法
查看>>
Node+Express连接mysql实现增删改查
查看>>
node, nvm, npm,pnpm,以前简单的前端环境为什么越来越复杂
查看>>
Node-RED中Button按钮组件和TextInput文字输入组件的使用
查看>>
Node-RED中Switch开关和Dropdown选择组件的使用
查看>>
Node-RED中使用html节点爬取HTML网页资料之爬取Node-RED的最新版本
查看>>
Node-RED中使用JSON数据建立web网站
查看>>
Node-RED中使用json节点解析JSON数据
查看>>
Node-RED中使用node-random节点来实现随机数在折线图中显示
查看>>
Node-RED中使用node-red-browser-utils节点实现选择Windows操作系统中的文件并实现图片预览
查看>>