kotlin的可空性,空安全

Kotlin 与 Java 互操作指南:空安全在跨语言开发中的实战演进 本文深入探讨Kotlin与Java互操作中的空安全问题,揭示了平台类型(Platform Types)带来的潜在风险。通过15个典型场景分析,文章系统性地提出解决方案:利用类型注解映射、编译警告增强、防御性编码等机制处理跨语言空指针异常;针对泛型、SAM接口等复杂场景,提出类型投影和安全适配器模式;结合Android实际案例展示空安全最佳实践。文章还剖析了编译器底层技术,提供契约、扩展函数等优化工具,并总结架构设计模式与性能优化方案,为构建健壮的混合语言项目提供完整方法论。 阅读详情

一,可空性

可空性是 Kotlin 类型系统中帮助你避免 NullPointerException 错误的特性。 作为一个程序的用户,你很可能见过像这样干巴巴的错误信息“An error has occurred: java.lang.NullPointerException”(发生了错误 : java.lang.NullPointerException)。 这条信息还有另外一个版本“Unfortunately, the application X has stopped”(对不起, X 应 用程序己停止),其背后的隐藏原因往往也是 NullPointerException。这样的 错误让用户和开发者都觉得庆烦。

现代编程语言包括 Koti in 解决这类问题的方法是把运行时的错误转变成编译期 的错误。通过支持作为类型系统的一部分的可空性,编译器就能在编译期发现很多 潜在的错误,从而减少运行时抛出异常的可能性。

二,可空类型

Kotlin 和 Java 的类型系统之间第一条也可能是最重要的一条区别是, Kotlin 对可空类型的显式的支持。这意味着什么呢?这是一种指出你的程序中哪些变量和属 性允许为 null 的方式。如果一个变量可以为 null,对变量的方法的调用就是不安全的,因为这样会导致 NullPointerException。 Kotlin 不允许这样的调用, 因而可以阻止许多可能的异常

fun strLen(s: String) = s.length

strLen(null)

如上面的代码和调用是会报Error的。
ERROR: Null can not be a value of a non-null type String

在kotlin中我们用“问号 ?”来表示可空
type? = type or null
问号加在任何类型的后面表示这个类型的变量可以存储Null引用。
重申一下,没有问号的类型表示这种类型的变量不能存储null引用,这说明所有常见类型默认都是非空的。除非显式的把它标记为可空。

还是上面的代码,如果加上“问号?” 支持可空类型

fun strLen(s: String?) = s.length

因为s支持null的引用,这个时候s.length是会报异常的。所以这行代码会有Error提示
ERROR: only safe (?) or non null asserted (! !.) calls are allowed on a nullable receiver of type kotlin.String?

所以正确的写法应该是

fun strLenSafa(s: String?): Int = if(s != null) s.length else 0

增加了null引用的判断就不会有问题了。

三,可空安全调用的几种运算符

安全调用运算符”?.”

可以说是Kotlin中最有效的一种安全调用运算符,它允许你把一次null检查和一次方法调用合并成一个操作
s?.toUpperCase() 等同于下面的写法:

if(s != null) s.toUpperCase() esle null

换句话说如果你试图调用一个非空的方法,这次方法调用会被正常执行,但是如果值是null,这次调用不会发生,二整个表达式的值为null

fun strLen1(s: String?) = s?.length

类似于这种写法,当s不为空的时候 返回的是一个int长度,但是当为空的时候并不会返回一个0,而是null

class Address(val streetAddress: String, val zipCode: Int, val city: String, val country: String)
class Company(val name: String, val address: Address?)
class Person1(val name: String, val company: Company?)

fun printShippingLabel(person: Person1) {
    val address = person.company?.address ?: throw IllegalArgumentException("No Address")
    with(address) {
        println(streetAddress)
        println("$zipCode  $city,  $country")
    }
}

带null检查的方法调用序列在java中太常见了。类似于上面的这种,kotlin可以让他们变得更加简洁。

Elvis运算符“?:”

kotlin有更方便的运算符来提供null的默认值

fun foo(s: String?) {
    val t: String = s ?: ""
    println("zifu:" + t)
}

如果s为null,结果就是一个空字符串

Elvis 运算符接收两个运算数,如果第一个运算数不为 null,运算结果就是第 一个运算数;如果第一个运算数为 null,运算结果就是第二个运算数。

fun strLengthSafe(s: String): Int = s?.length ?: 0

安全转换“as?”

as 运算符。和 常规的 Java 类型转换一样,如果被转换的值不是你试图转换的类型,就会抛出 ClassCastException 异常。当然可以结合 is 检查来确保这个值拥有合适的类型。 但是作为一种安全简洁的语言, Kotlin 没有更优雅的解决方案吗?当然有。

as ?运算符尝试把值转换成指定的类型, 如果值不是合适的类型就返回 null,
一种常见的模式是把安全转换和 Elvis 运算符结合使用。例如,实现 equals 方法的时候这样的用法非常方便。

class Person(val firstName: String,val lastName: String){
    override fun equals(o: Any?): Boolean{
        val otherPerson = o as? Person ?: return false
        return otherPerson.firstName == firstName && otherPerson.lastName == lastName
    }

    override fun hashCode(): Int = firstName.hashCode() * 37 + lastName.hashCode
}

使用这种模式,可以非常容易地检查实参是否是适当的类型,转换它,并在它 的类型不正确时返回 false,而且这些操作全部在同一个表达式中。当然,这种场 景下智能转换也会生效 : 当你检查过类型并拒绝了 null 值,编译器就确定了变量 otherPerson 值的类型是 Person 并让你能够相应地使用它。

非空断言“!!”

非空断言是 Kotlin 提供给你的最简单直率的处理可空类型值的工具。它使用双感叹号表示,可以把任何值转换成非空类型。如果对 null 值做非空断言,则会抛出异常
如前面的代码

fun strLen(s: String?) = s.length
fun strLen(s: String?) = s!!.length

第一行代码会报Error,但是第二行就不会了。可以顺利编译通过。
如果第二行中的s为null会发生什么?kotlin没有其他选择,只会抛出空指针异常。

“let”函数

let 函数让处理可空表达式变得更容易。 和安全调用运算符一起,它允许你对表达式求值,检查求值结果是否为 null,并把结果保存为一个变量。 所有这些动作都在同一个简洁的表达式中。

fun sendEmailTo(email: String) {
    println("Sending email to $email")
}

var email: String? = "yole@example.com"
    email?.let { sendEmailTo(it) }
    email = null
    email?.let { sendEmailTo(it) }

如果email = null则下面的一行代码不会被调用

可空类型的扩展

为可空类型定义扩展函数是一种更强大的处理 null 值的方式。可以允许接收 者为 null 的(扩展函数)调用,并在该函数中处理 null,而不是在确保变量不 为 null 之后再调用它的方法。只有扩展函数才能做到这一点,普通成员方法的调 用是通过对象实例来分发的,因此实例为 null 时(成员方法)永远不能被执行。

Kotlin 标准库中定义的 String 的两个扩展函数 isEmpty 和 isBlank 就 是这样的例子。第一个函数判断字符串是否是一个空的字符串 ””。第二个函数 则判断它是否是空的或者它只包含空白字符。通常用这些函数来检查字符串是有 价值的,以确保对它的操作是有意义的。你可能意识到了,像处理无意义的空字 符串和空白字符串这样处理 null 也很有用。事实上,你的确可以这样做:函数 isEmptyOrNull 和 isNullOrBlank 就可以由 String?类型的接收者调用。

fun verifyUserInput(input: String){
    if(input.isNullOrBlank()){
        println("please fill in the required fields")
    }
}

函数 isNullOrBlank 显式地检查了 null ,这种情况下返回 true ,然后调 用 isBlank,它只能在非空 String 上调用:

fun String?.isNullOrBlank(): Boolean = this == null || this.isBlank()

以上,描述了kotlin关于可空,和空处理的几种方式。

参考:《实战kotlin》

示例代码:https://github.com/wangxp423/ExerciseKt

kotlin之Android项目实战

​​光流结合深度学习实现物体运动方向判断 光流计算:提取每一帧视频中像素的运动信息,生成光流图。光流特征提取:通过特定的预处理,将光流图转换为深度学习模型可用的输入格式。深度学习模型设计:构建一个卷积神经网络(CNN)或其他适合的深度学习架构,利用光流特征进行运动方向分类。模型训练与推理:对网络进行训练并使用训练好的模型判断运动方向。光流与深度学习结合的运动方向判断技术在多个领域具有广泛的应用前景。通过光流提取像素级动态信息,并利用深度学习模型学习高层次特征,可以实现高精度的运动检测与方向判断。 阅读详情

相关推荐

APO的全面进化之路(2):走向IBP、建设端到端供应链计划体系

前一篇记录阐述了在供应链计划(Supply Chain Planning)领域里SAP的关键产品APO的不断进化之路,即部分产品从APO进化到S/4HANA,本篇将继续阐述进化之路上的另一大中坚产品力量SAP-IBP(Integrated Business Planning)。作为SAP数字化供应链(Digital Supply Chain)中供应链计划SCP的左膀右臂,S/4HANA与IBP共同完善了计划域的完整闭环。本篇作为收尾,在先谈对IBP产品的个人认知之前,特别是在当今这个IT产品迭代多、技术革新

ChampaignWolf的专栏 5227

【Kotlin学习】Kotlin的类型系统——可空性

学习于《Kotlin实战》,本文讲解了kotlin的一个特性——可空性,其中包含了安全调用运算符、Elvis运算符、安全转换、非空断言、let函数、lateinit等内容

PanicLin的博客 1741

保姆级教程:用AdGuard DNS代理实现全设备广告过滤(含Win/Mac/安卓/iOS配置)

本文提供了一份详尽的AdGuard DNS代理配置指南,帮助用户在全设备(Win/Mac/安卓/iOS)上实现广告过滤。通过系统级DNS设置,AdGuard能有效拦截广告、跟踪器和恶意网站,提升隐私保护和浏览效率。教程涵盖原理说明、各平台配置步骤及高级优化技巧,适合不同技术水平的用户。

weixin_42656416的博客 819

四、kotlin的可空性和基本数据类型

是一种可以为 的类型, 本质是下面这样: 作用 在不影响程序运行性能的前提下, 显示的帮助程序员避免空指针异常 在java中这样容易出现空指针异常 在实际的java项目, 都需要 判断 当然 之后出现的 , 但还是麻烦的, 不仅使代码变得冗长而且还存在性能问题 使用 kotlin 重写这个函数前需要程序员主动判断该函数是否接受实参为空的情况, 如果需要支持的话, 在上面代码中, 如果 为 的话, 则该函数直接返回 , 函数调用者 可以借助返回值 使用 判断是否为空如果实参一定不为

bangiao的博客 806

VLA算法总结对比——RT1 / RT2 / Pi0 / Octo/ RDT / OpenVLA

本文主要针最近比较经典的VLA算法进行对比总结,暂不涉及到代码细节和实验细节上的展开,仅仅是从大面上掌握下目前VLA的一些思路和方法。

weixin_44580210的博客 9492

基于Python的SEC Edgar文件高效爬取:最新技术与实战指南

本文详细介绍了如何使用Python最新技术高效爬取SEC Edgar数据库中的金融文件。我们将探讨SEC Edgar系统的结构、合法爬取注意事项,并使用现代Python库如Requests-HTML、aiohttp和Playwright实现多种爬取方案。文章包含完整的代码示例、性能优化技巧以及数据处理方法,为金融数据分析师、研究人员和开发者提供全面指导。关键词:SEC Edgar、Python爬虫、金融数据、异步爬取、Playwright、XBRL解析。

2201_76125261的博客 633

Kotlin中的可空类型

在 Kotlin 中,可空类型是一项重要的特性,它允许我们声明变量可以为空。在本篇博客中,我们将介绍 Kotlin 中的可空类型,并提供示例代码演示如何处理可空变量、使用安全调用操作符(,它会将任何变量(可空类型变量或非空类型变量)转换为非空类型的变量。但是需要注意,如果该变量为空,则会抛出异常。首先,让我们来看一下如何声明可空类型变量。接下来,我们将演示如何处理可空变量。,我们可以更加灵活地处理可空变量,避免空指针异常的发生。是一个可空类型的变量,它可以存储一个。将变量的类型标记为可空类型。

一起coding,一起嗨。 607

nvidia jetson orin调试 MAX96712 serdes相机(SG2-AR0233C-GMSL2)

背景:想了解一下关于nvidia orin camera相关的模块,基于Drive Orin demo板的话,没有合适的相机,用 nvsipl框架点亮 GMSL相机不知如何下手,那么基于nvidia Jetson orin的话,目前国内有对应的转接板以及GMSL相机可以参考,基于此,那么本文详细记录一下关于nvidia orin的相关踩坑记录;需要Nvidia Jetson Orin开发板一个,MIPI转接板一个,MIPI转GMSL转接板一个,GMSL线束(fakra单线束),GMSL摄像头一个。

qq_30025621的博客 4444

【Kotlin】空安全总结 ( 变量可空性 - 手动空安全管理 - 空安全调用操作符 - 非空断言操作符 - 空合并操作符 - 空指针异常处理 - 先决条件函数判空 )

在下面的代码中 ,声明了自定义 异常类, 其继承了空指针异常类 ,在调用name变量成员时 , 先调用checkNull函数 ,检查该变量是否为空 ,使用str?代码 , 其中 空合并操作符 判定str是否为空 ,如果为空 , 则抛出异常;= null// 捕获并处理异常try {name!!.count();class MyException: KotlinNullPointerException("空指针")MyException: 空指针。

xnxqwzy的博客 1633

AutoSAR系列讲解(入门篇)2.2-SWC的类型

该章讲解了两种SWC的分类,并且映射到实际的工程中应该是具体的什么文件类型

雪云飞星的博客 4万+

4、同轴3 - RRR球面并联机构运动分析与自主移动农业水果采摘机器人设计

本文研究了同轴3-RRR球面并联机构的运动学与速度分析,采用几何与数值方法进行位置分析,并利用螺旋理论简化雅可比矩阵的推导,通过ADAMS仿真验证了结果的准确性。同时提出一种新型自主移动农业水果采摘机器人设计,具备多功能末端执行器、水果软管转移系统和配重式静态稳定性结构,旨在减少采摘损伤、提升效率。文章还探讨了该机构在机器人控制与仿真中的应用潜力,以及采摘机器人在智能化升级与多机协作方面的发展方向。

y4z5a6b7的博客 246

Kotlin 语言学习(6) - Kotlin 的可空性

一、本文概要 二、可空性 2.1 可空类型 当我们在声明方法时,如果允许在这个方法被调用的时候传给它null的实参,则需要显示地在类型名称后面加上问号来标记它: 问号可以加在任何类型的后面来表示这个类型的变量可以存储null引用,而所有常见类型默认都是非空的,除非显示地把它标记为可空。 当你有一个可空类型的值,对它的操作也会受到限制: 不能调用它的方法 不能把它赋值给非...

蒙的博客 963

【K8S系列】Kubernetes Pod节点CrashLoopBackOff 状态及解决方案详解【已解决】

在 Kubernetes 中,Pod 的状态为 **`CrashLoopBackOff`** 表示某个容器在启动后崩溃,Kubernetes > 尝试重启该容器,但由于持续崩溃,重启的间隔时间逐渐增加。下面将详细介绍 `CrashLoopBackOff > `状态的原因、解决方案及相关命令的输出解释。

颜淡慕潇 8380

【Kotlin】空安全 ① ( Kotlin 的空安全机制 | 变量可空性 | 默认变量不可赋空值 | 声明可空类型变量 )

一、Kotlin 的空安全机制、 二、变量可空性、 1、默认变量不可赋空值、 2、声明可空类型变量、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 1049

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

【Kotlin】空安全总结 ( 变量可空性 | 手动空安全管理 | 空安全调用操作符 | 非空断言操作符 | 空合并操作符 | 空指针异常处理 | 先决条件函数判空 )

一、Kotlin 的空安全机制、 二、变量可空性、 三、手动空安全管理、 四、空安全调用操作符 ?、 五、let 函数结合空安全调用操作符使用、 六、非空断言操作符 !!、 七、使用 if 语句判空、 八、空合并操作符 ?:、 九、空合并操作符与 let 函数结合使用、 十、空指针异常处理、 十一、先决条件函数判空

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 3417

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

在 Android 11 及更高版本系统中处理可空性

作者 / David Winer, Kotlin 产品经理在去年 5 月的 I/O 开发者大会上,我们正式宣布 Kotlin 优先 (Kotlin First) 的这一重要理念,Kotl...

谷歌开发者 1000

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【Kotlin 初学者】空安全与异常

Kotlin 的类型系统旨在从我们的代码中消除NullPointerException。异常是程序中发生的运行时问题,导致程序终止。

帅次的博客 2836

Kotlin-40.kotlin调用Java之二(Call Java from Kotlin)

Java空安全和平台类型Null-Safety Platform Type;在Java中任何引用都可能是null,Java类型在Kotlin被特别对待;Java类型映射(Mapped type);Java基本类型映射到相应Kotlin类型;Java包装类(基本类型)映射成可空Kotlin类;Java集合类型在Kotlin中既能只读,也能可变,因此有以下映射;Java数组在Kotlin中映射;Java泛型kotlin

http://lioil.win 1220

第三章:kotlin基本语法:var和val、?和!!的区别

var和val var:可变变量 var <标识符> : <类型> = <初始化值> 例: var a :Int? = 10 var b = 10 (编译器支持自动类型判断) var list :ArrayList<String> ? = null val:不可变变量(一旦赋值不可修改) val<标识符> :<类型> = <初始化值> 例: val a :Int a = 10 val b :In...

qq_38524537的博客 966

Kotlin空安全机制的编译期检查深度解析(75)

空引用(Null Reference)问题是软件开发中常见的错误来源。在传统的面向对象语言(如Java)中,任何对象引用都可能为null,这意味着在使用对象引用之前必须进行null检查,否则可能会抛出NullPointerException(NPE)。

Android开发领域创作者 964

一起学Kotlin(3)

本节主要学习下空安全,在Java中经常会被空指针异常玩得死去活来的,那在Kotlin中又是如何处理的呢,Let`s go! 在Java中,我们经常会被NullPointerException折磨,带来了许多麻烦,编码经常需要战战兢兢,以至于我听到了部分人员提出了不管什么时候在使用之前都必须要判空的逻辑,嗯哪怕是上一步进行了new的操作后一步使用也要判空的逻辑感觉有点过了,但可见被NullPointerException毒害之深。那么Kotlin作为更强大的语言,势必会基于以往的语言设计经验对其进行改良。Ko

calm1516的专栏 480

Kotlin初级(2)- - - 空安全.md

空类型、空安全 为了解决类似NPE这类的问题,现代编程语言包括Kotlin解决这类问题的方法就是把运行时的错误转变成编译期的错误。通过支持作为类型系统的一部分的可空性,编译器就能在编译期发现很多潜在的错误,从而减少运行时抛出异常的可能性 变量的定义 Kotlin中的变量修饰符只有两个 val修饰的变量不能重新被赋值 var修饰的变量可以被重新赋值 var修饰的变量不可为null,val修...

Hankkin的博客小园 537
上一篇: Java设计模式汇总(全)
下一篇: kotlin-委托属性以及在SharedPreferences中的应用
wangxp423
博客等级 码龄9年 35粉丝 64原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值