Kotlin 空类型安全与智能类型转换
SegmentFault
共 3179字,需浏览 7分钟
· 2021-01-16
一、前言
在 Kotlin 中的类与接口 中我们已经讲了 Kotlin 的 类、接口 和 扩展方法,今天我们来讲 Kotlin 中的 空类型安全 和 智能类型转换。
二、Kotlin 空类型安全
2.1、空类型安全概念
Java 语言中是没有空类型安全这一概念的,所以写 Java 代码经常会出现空指针异常,但是 Kotlin 致力于消除空引用所带来的危险,所以就有了空类型安全概念。
下面这段代码在 Kotlin 中是无法编译通过的,因为 Kotlin 的 String 是不能接受空值的,所以这个赋值操作是不被允许的。
var nonNull: String = "Hello"
nonNull = null // 不可空类型,不能赋值为 null
// 访问长度的话,不需要空判断
val length = nonNull.length
IDE 报错如下所示:
但是如果我们非得定义一个空值,也是有办法的,Kotlin 为了 100% 兼容 Java,必须得实现接收空值,所以要接收空值可以在定义的时候加一个 ?。
但是这个时候这个变量就可能是空值,所以访问的时候就会比较严格,比如下面代码中的 nullable.length 就会报错,因为可能触发空指针异常。
var nullable: String? = "Hello"
nullable = null // 可空类型,编译通过
val length = nullable.length // 可能触发空指针,编译保报错
IDE 报错如下所示:
这个时候我们想 nullable.length 不报错可以:
当我们确定 nullable 不可能为空的时候,可以将 nullable 强转为不可空类型,如下所示: var nullable: String? = "Hello"
// 不会报错了(自己已经知道了,这个 nullable 不可能为空)
val length = nullable!!.length如果我们不确定 nullable 是否为空的时候,可以用 ?. 来实现安全访问,如下所示: var nullable: String? = "Hello"
// 这种情况下如果 nullable 为空的话,那么返回的 length 也是空
val length = nullable?.length
// 这时候 length 的类型不是 Int,而是 Int?,所以可以写成下面这样
val length: Int? = nullable?.length
// 如果你想 length 的类型是 Int 的话,可以加个默认值,写成下面这样
val length: Int = nullable?.length ?: 0 // 如果 nullable?.length 为空, 就返回0
2.2、空类型的继承关系
我们知道 Int 是 Number 的子类,所以通过下面的代码我们就可以知道 String 应该是 String? 的子类。
var a: Int = 2
var b: Number = 10.0
a = b // Type mismatch,报错
b = a // OK
var x: String = "Hello"
var y: String? = "World"
x = y // Type mismatch,报错
y = x // OK
2.3、Kotlin 空类型安全回顾
三、Kotlin 智能类型转换
3.1、智能类型转换例子
// 定义一个接口
public interface Kotliner {
}
// 定义一个类 Person 实现 Kotliner 接口
public class Person implements Kotliner {
public final String name;
public final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
// 用子类的实例赋值给接口的引用
Kotliner kotliner = new Person("Test", 20);
// 这里已经判断了是不是 Person,但是下面还是要强制类型转换
if (kotliner instanceof Person) {
System.out.println(kotliner.name); // 这样写报错
System.out.println(((Person) kotliner).name); // 正确写法
}
}
}
val kotliner: Kotliner = Person("Test", 20)
if (kotliner is Person) {
println((kotliner as Person).name) // 不需要强转,可以智能转换,所以下面的写法就可以了
println(kotliner.name)
}
下面这段代码定义了一个 value, 类型是 String?,if 判断其不为空,所以在 if 判断这个括号里面,value 的类型会被智能转换成 String,当然出了括号,value 的类型就又是 String? 了。
var value: String? = null
value = "Test"
if (value != null) {
// value: String? ==> String
println(value.length)
}
// value: String?
...
3.2、不支持智能类型转换的情况
下面这种情况就不支持智能类型转换,因为这个公共变量很多地方都可以访问,所以我们在判断不为空之后,有可能别的线程又把 tag 改成了空,所以这种情况智能类型转换就失效了。
// 在 main 函数之外定义一个公共变量
var tag: String? = null
fun main() {
if(tag != null) {
// 有可能被改成空
println(tag.length) // 报错,不支持智能类型转换
}
}
3.3、几个建议
尽可能使用 val 来声明不可变引用,让程序的含义更加清晰确定; 尽可能减少函数对外部变量的访问; 必要的时候曾创建局部变量指向外部变量,避免因它变化引起程序错误。
3.4、Kotlin 智能类型转换
四、小结
五、源码
评论
字节的跳动职级与薪资(2024年)
上一篇:阿里公布年终奖,P7, 3.5+,22W年终奖,还有35W长期现金激励,真香字节跳动自2012年3月成立以来,已经迅速成长为一个全球性的科技公司。其产品和服务已经遍布全球150多个国家与地区,并且支持超过75种不同的语言。在字节跳动的官方网站上,列出了一系列引人注目的产品和服务,包括但不限于
开发者全社区
0
光纤详解:光纤跳线如何分类,多向单模转换?
本文来自“光纤详解:光纤跳线如何分类,多向单模转换?”,光纤跳线作为光网络布线最基础的元件之一,被广泛应用于光纤链路的搭建中。如今,光纤制造商根据应用场景的不同推出众多类型的光纤跳线,如MPO/LC/SC/FC/ST光纤跳线,单工/双工光纤跳线,单模/多模光纤跳线等,它们之间各有特色,且不可替代。本
架构师技术联盟
0
管理世界2024 | 使用管理层讨论与分析测量「企业人工智能指标」
Tips: 公众号推送后内容只能更改一次,且只能改20字符。如果内容出问题,或者想更新内容, 只能重复推送。为了更好的阅读体验,建议阅读本文博客版, 链接地址 https://textdata.cn/blog/2024-04-19-ai-improve-firm-productivity/
大邓和他的Python
0
APP 安全测试项总结
一、安装包测试 1.1、关于反编译 目的是为了保护公司的知识产权和安全方面的考虑等,一些程序开发人员会在源码中硬编码一些敏感信息,如密码。而且若程序内部一些设计欠佳的逻辑,也可能隐含漏洞,一旦源码泄漏,安全隐患巨大。 为了避免这些问题,除了代码审核外,通常开发的做法是对代码进行混淆,混淆后源代
测试开发技术
0
国产算力训练大模型的经验与教训
本文来自“国产算力训练大模型的经验与教训”。本文介绍大模型的计算特征(国产平台介绍、系统挑战、算子实现、容错)、框架的并行性支持、未来算法等。随着ChatGPT的横空出世,人工智能大模型成为各行各业热议的焦点,国内外各种大模型如雨后春笋般涌现,引发了新一轮人工智能热潮。但在看到大模型取得巨大进步的同
架构师技术联盟
1
Java与lua互相调用简单教程
来源:网络👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 / 赠书福利全栈前后端分离博客项目 2.0 版本完结啦, 演示链接:http://116.62.199.48/ ,新项目
小哈学Java
0
【送书福利】《Java面试八股文:高频面试题与求职攻略一本通》
先来唠唠最近粉丝面试回来跟我聊天,基本上都提到一个点,在面试过程中八股文占比很高(八股文70%、项目20%、10%算法)除了一些搞算法突出的厂除外。其实现在很多厂八股都是逐渐深入的方式来问,所以大家在学习的过程中,针对一些重点的内容,最好深入去学习,不然还是比较难应对这种追问式的问题。最近刚好从一位
Java后端技术
0
微服务与领域驱动设计,架构实践总结
来源:知了一笑👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 / 赠书福利全栈前后端分离博客项目 2.0 版本完结啦, 演示链接:http://116.62.199.48/ ,新
小哈学Java
0