Kotlin null的处理详解
发布时间 - 2026-01-11 01:43:49 点击率:次Kotlin null的处理详解

NullPointerException,俗称NPE,不管菜鸟还是老鸟们,都是不可避免,经常遇到的一个异常,解释起来很简单,就“空指针”三个字。总是在一次不小心,而掉进这个陷阱里。Kotlin 的设计目标就是希望消除代码中 null 引用带来的危险, 也就是所谓的造成十亿美元损失的大错误.
NPE的原因
尽管Kotlin希望消除代码中的NPE,我们总是不小心,总会不小心又掉进NPE的陷阱,下面是可能NPE的原因:
- 明确调用 throw NullPointerException()
- 使用 !! 操作符
- 外部的 Java 代码导致这个异常
- 初始化过程中存在某些数据不一致 (在构造器中使用了未初始化的 this)
避免NPE
在Kotlin中,明确区分可以指向 null 的引用 (可为 null 引用) 与不可以指向null的引用 (非null引用). 比如, 一个通常的 String 类型变量不可以指向 null:
var a: String = "abc" a = null // 编译错误
此时,你对a变量的任何调用都是安全的,因为它为非null,你可以对该引用做任何操作而不会报NPE。就算对a赋值给Null,编译器都会报错,不会让你通过。
可是,实际开发时,不可能所有的变量不会null,总会有情况,变量是null的,此时该如何设定该变量呢?要允许null值的变量, 我们可以将变量声明为可为null的字符串, 写作 String? :
var b: String? = "abc" b = null // ok
这样,我们是解决了变量可以设置为null的问题,可NPE的这个陷阱又设上了,如果再粗心大意,NPE又来找麻烦了。
如果我们仍然需要访问这个属性, 对不对? 有以下几种方法可以实现:
在条件语句中进行null检查
通过条件语句,对变量检查是否为null,对 null 和非 null 的两种情况分别处理:
if (b != null && b.length > 0)
print("String of length ${b.length}")
else
print("Empty string")
注:
该方案只是针对当前b的值,b的值在检查以后,如果b的值被修改仍需对此值做非null检查,也就是说每次修改b的值,都必须对b作非null验证,这也导致了代码的冗余。
安全调用
什么是安全调用?看起来有点不理解,既然是null怎么还会有安全呢?
b?.length
在Kotlin中,允许使用 “?.”操作符调用变量,其含义是如果b不是null,这个表达式将会返回b.length,否则返回 null.如果使用了”?.”,其表达式的值也应为 可为null的,比如Int?,否则编译器会报错。
bob?.department?.head?.name
安全调用在链式调用的情况下非常有用.这样的链式调用, 只要属性链中任何一个属性为 null, 整个表达式就会返回 null.
?:操作符
如果 ?: 左侧的表达式值不是null, 就会返回表达式的的值,否则, 返回右侧表达式的值.
val l = b?.length ?: -1
如果b不为null,将返回b的长度,如果为null,将返回-1
注:
只有在左侧表达式值为 null 时, 才会计算右侧表达式.
由于在 Kotlin 中 throw 和 return 都是表达式, 因此它们也可以用在 Elvis 操作符的右侧. 这种用法可以带来很大的方便, 比如, 可以用来检查函数参数值是否合法。
fun foo(node: Node): String? {
val parent = node.getParent() ?: return null
val name = node.getName() ?: throw IllegalArgumentException(“name expected”)
// …
}
!! 操作符
对于b不为null的情况, 这个表达式将会返回这个非null值(比如, 在我们的例子中就是一个 String 类型值), 如果b是 null, 这个表达式就
会抛出一个 NPE:
val l = b!!.length()
当b为null时就抛出一个异常,你可以捕获它,而不是在不知道在某一角落里调用时,才报出异常,抓头挠腮半天,才找到NPE在哪里。
安全的类型转换
如果对象不是我们期望的目标类型, 那么通常的类型转换就会导致ClassCastException,可以选择使用安全的类型转换, 如果转换不成功, 它将会返回 null,这样避免了转换异常的抛出。
val aInt: Int? = a as? Int
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# Kotlin
# null的处理
# null
# Kotlin浅析null操作方法
# 都是
# 就会
# 链式
# 将会
# 可为
# 抛出
# 不可以
# 而不
# 不为
# 报错
# 会报
# 掉进
# 是一个
# 使用了
# 是在
# 会有
# 让你
# 不可能
# 菜鸟
# 你可以
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
微信公众帐号开发教程之图文消息全攻略
Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康
Laravel如何处理CORS跨域请求?(配置示例)
Laravel如何实现密码重置功能_Laravel密码找回与重置流程
如何批量查询域名的建站时间记录?
如何在景安服务器上快速搭建个人网站?
JavaScript如何操作视频_媒体API怎么控制播放
Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件
济南网站建设制作公司,室内设计网站一般都有哪些功能?
Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】
Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言
详解Oracle修改字段类型方法总结
edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】
Laravel如何为API生成Swagger或OpenAPI文档
Laravel如何生成API文档?(Swagger/OpenAPI教程)
网站页面设计需要考虑到这些问题
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】
Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】
Laravel怎么实现支付功能_Laravel集成支付宝微信支付
Laravel集合Collection怎么用_Laravel集合常用函数详解
南京网站制作费用,南京远驱官方网站?
Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】
C#如何调用原生C++ COM对象详解
Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层
如何在万网ECS上快速搭建专属网站?
如何用花生壳三步快速搭建专属网站?
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?
Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控
如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环
Laravel观察者模式如何使用_Laravel Model Observer配置
Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能
Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】
Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全
Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives
浅谈redis在项目中的应用
Python文件异常处理策略_健壮性说明【指导】
高端建站如何打造兼具美学与转化的品牌官网?
Laravel如何与Inertia.js和Vue/React构建现代单页应用
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
Laravel怎么实现微信登录_Laravel Socialite第三方登录集成
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】
移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?
如何快速搭建高效WAP手机网站吸引移动用户?
Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布
如何在阿里云通过域名搭建网站?
再谈Python中的字符串与字符编码(推荐)
Laravel如何处理文件下载请求?(Response示例)
Laravel如何记录自定义日志?(Log频道配置)

