Kotlin开发笔记:类型安全和转换

news2024/11/25 22:57:28

Kotlin开发笔记:类型安全

在这里插入图片描述

类型安全是编程中非常重要的内容,在实际编程中我们总是会遇到许许多多的空指针异常,类型错误等异常。因此解决好类型安全的问题可以大大提升程序的健壮性。同时Kotlin针对类型安全就引入了许多有用的机制,它将帮助我们走向防御型编程的道路。本篇文章就将介绍关于Kotlin类型安全的相关信息。

Any类和Nothing类

首先我们将先介绍Kotlin中的两个特殊类:Any类和Nothing类。

Any类

Kotlin中的所有类都继承于Any类,就是相当于Java中的Object类。Any类的最大目的不是让我们将变量,参数或者返回类型定义为Any类,而是提供了一些通用方法,比如像equals,hashCode和toString等像在Object类中定义的方法一样。

当然,Any类和Object类也不是完全相同的,Any通过拓展函数提供了一些特殊的方法。比如像to拓展函数,拓展函数的相关内容将在后面介绍。

Nothing类

在Java中,我们使用void表示方法不返回任何东西,但在Kotlin中,使用Unit来告诉我们什么时候函数没有返回任何有用的东西。那什么都没有返回的情况如何表示呢?Kotlin中用Nothing类来表示实际上一个函数什么也没有返回。

Nothing类没有实例,它表示一个永远不存在的值或者结果。当用作方法的返回类型时,意味着函数永远不会返回–函数调用只会导致异常。在实际编写时,我们也会发现无法返回Nothing的实例。

Nothing的一个独特能力是它可以代表任何东西,也就是说Nothing可以替代任何类,包括Int,Double,String等。比如说:

fun computeSqrt(n:Double):Double{
    if(n >= 0){
        return Math.sqrt(n)
    }else{
        throw java.lang.RuntimeException("Error!")
    }
}

else部分的异常就用Nothing表示,为了帮助我们理解我们可以看看Nothing给出的提示:
在这里插入图片描述
翻译过来,大概就是在说:

凡事皆有实例。你可以用Nothing来表示“一个永远不存在的值”:例如,如果一个函数的返回类型是Nothing,这意味着它永远不会返回(总是抛出异常)。

总的来说,编译器可以确定if表达式的返回类型,在本例中为Double类型。因此,Nothing的唯一目的就是能够帮助编译器验证程序中类型的完整性是健全的。

可空的引用

在Java中,我们遇到的最头疼的问题应该就是空指针引用异常了,null是一种我们一直无法解决的问题。如果对null对象进行方法调用,就会导致空指针异常,因此在对可能为空的对象进行方法调用时,最安全的做法就是对该对象进行检查。

而在Kotlin中是不允许我们随便将null赋值给任意引用的,对于可能为null的引用,我们应该使用可空引用。根据引用是否为空,我们可以将引用分为普通引用和可空引用。普通引用是不能被赋值为null的,对应的,可空引用就允许我们将null赋值给它。

普通引用和可空引用的区别也很简单,就是可空引用在普通引用的后面加了一个?,我们看下面这个表:

可空引用普通引用
Int?Int
Double?Double
String?String
List< String >?List< String >

具体也就是这么个规律,很简单。

使用可空类型

进行非空判断

前面提到可空类型的实际引用可能为null,那么在调用引用时就可能会出现空指针异常,所以在Kotlin中我们对可空类型进行方法调用时就需要先进行非空检查,否则编译器就会报错,比如:

fun nikeName(name:String?):String?{
        //可空类型
        if(name == "William"){
                return "Bill"
        }
        return name.reversed()
}

这段代码就会报错,因为name为可空类型,对可空类型进行方法调用前要进行检查,比如我们要修改成这样:

fun nikeName(name:String?):String?{
        //可空类型
        if(name == "William"){
                return "Bill"
        }
        if(name != null){
       		 return name.reversed()
        }
        return null
}

这次在方法调用前我们进行了非空判断,这样就可以正确运行了。

安全调用运算符

像上面一样每次要调用非空引用的方法时都要进行非空判别的话就很麻烦,Kotlin中也提供了方便的运算符来实现上面的效果比如说:

if(name != null){
	return name.reversed()
}
return null

我们就可以使用这一行来代替:

return name?.reversed()

这个?.就是安全运算符,该运算符会先判断可空引用是否为空,如果不为空就会接着调用后面的方法,否则会直接返回null,这就优雅了许多。

Elvis运算符

上面提到的安全运算符在引用为空的情况下会返回null,但是如果我们不想要返回null呢?这时就可以使用Elvis运算符了,?:就是Elvis运算符。我们来给出两段效果一致的代码来帮助我们理解这个运算符的效果:

val result = name?.reversed()?.toUpperCase()
return if(result == null) "Joker" else result

如果使用Elvis运算符是这样的:

return name?.reversed()?.toUpperCase() ?: "Joker"

可以说,我们使用安全调用运算符加上Elvis可以大大提升我们代码的健壮性同时又不失优雅。

断言运算符(不安全!!!)

除了上面两种安全的运算符之外,还有一个不太安全的断言运算符,同时也不太建议使用。断言运算符将强制使编译器停止检查,使得非空引用在不经过非空判断就可以进行方法调用,显然这种使用会导致空指针异常,也不太简易使用它,不过这里还是给出一个示例:

return name!!.reversed().toUpperCase()

这个!!就是断言运算符,这两个感叹号可能也说明了这个运算符的危险性。

类型检查和转换

类型检查

有时候我们可能会想知道手头的对象是不是我们所期望的类型,这种情况下就要进行类型检查。在Java中我们会使用instanceof,而在Kotlin中我们使用is运算符。比如说:

override fun equals(other: Any?): Boolean {
         return other is Animal  //is 运算符,检查引用所指向对象是否属于特定类型 像InstanceOf
 }

is运算符用于检查引用所指向的对象是否属于特定类型,如果是,则返回true,否则为false。我们也可以使用带否定的is,比如说!is。

最后is运算符还有一个特性,那就是智能转换,如果使用了is运算符或者!is运算符,那么就会自动进行类型转换。

智能转换

具体来说,这个智能转换是和is运算符相关联的,当is运算符判定了一个引用是一个特定类型后,我们对该引用就不必再进行强制类型转化而是可以直接使用它。

比如说,我们有一个类为Cat,它有Int类型的age变量和String类型的name变量;同时我们还有一个Object类型的引用。一般来说,我们如果想把这个Object当做Cat来用的话是先用instanceof运算符,然后再将Object对象强制转化为Cat之后才能访问其成员变量,给出Java示例:

public void main(){
	Object feakCat = new Cat(10,"Kitty");
	if(feakCat instanceof Cat){
		String name = ((Cat)feakCat).name;
		int age = ((Cat)feakCat).age; 
		System.out.println("this cat's name is "+name+" ,and its age is "+age);
	}
}

可以看到,即使已经判断了feakCat是Cat的实例,我们仍需要对其进行强制类型转化,而在Kotlin中,当is运算符判断出了feakCat的类型后,我们就会自动得到类型转化:

fun main() {
    val feakCat:Any = Cat(10,"Kitty")
    if(feakCat is Cat){
        println("this cat's name is ${feakCat.name},and its age is ${feakCat.age}")
    }
}

这显然就优雅多了。

Kotlin将在可能的情况下自动应用智能转换。如果它可以确定引用的类型是特定类型,那么他将允许你避免使用转换。同样,一旦Kotlin确定了一个对象引用不为空,他就可以用用智能转换,来自动将可空类型转换为不可空类型,从而再次省去了显示转换。

显示类型转换

当然智能转换也不是万能的,在编译器不能确定类型时,就需要我们进行显示类型转换。Kotlin中提供了两个运算符来进行显示类型转换。分别是as和as?。

as运算符的作用就类似于Java中的强制类型转换,所以说它就有可能会转换出错,比如当被转换的类不是需要转成的类的子类时。
而as?运算符就是as运算符的安全版本,当转换成功时,它的效果与as运算符一致,而当转换出错时,它就会返回一个null引用,这样就不会爆出异常了。

在书中也给出了一些建议:

  1. 尽可能多地使用智能转换
  2. 只有在智能转换不是一个选项时才使用安全转换
  3. 不要使用不安全的转换

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/770437.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pytorch 2.0初探:和pytorch 1.13的速度对比

看到pytorch2.0出来了&#xff0c;而且宣传提速明显&#xff0c;一行代码即可提速43%左右&#xff1a; compiled_model torch.compile(model) We then measure speedups and validate accuracy across these models. Since speedups can be dependent on data-type, we measu…

Laf v1.0 发布:函数计算只有两种,30s 放弃的和 30s 上线的

一般情况下&#xff0c;开发一个系统都需要前端和后端&#xff0c;仅靠一个人几乎无法胜任&#xff0c;需要考虑的特性和功能非常多&#xff0c;比如&#xff1a; 需要一个数据库来存放数据&#xff1b;需要一个文件存储来存放各种文件&#xff0c;比如图片文件&#xff1b;后…

旅行社优惠卡app软件开发

旅游行业的不断发展&#xff0c;越来越多的旅行社开始推出各种优惠卡来吸引游客。而随着智能手机的普及&#xff0c;开发一款旅行社优惠卡APP软件成为了一种必然的趋势。 该软件的主要功能是提供旅行社的各种优惠卡信息&#xff0c;包括优惠卡的种类、价格、使用范围、有效…

0基础学习VR全景平台篇 第65篇:VR直播-如何创建VR直播

开启一次VR直播只需简单三步&#xff1a;VR直播相机连接网线并开机>新建一个直播活动>将直播活动的推流地址填入直播相机。 1、将鼠标移至【开始创作】菜单&#xff0c;点击【全景直播】。 2、进入VR直播活动的创建页面&#xff0c;根据国家互联网相关政策&#xff0c;创…

Vant源码解析(四)----Popup弹出层,详解样式方法

这个功能&#xff0c;自己也手写过&#xff0c;毕竟有很多弹窗的嘛。 我自己写就是&#xff1a;一个背景层&#xff0c;然后一个盒子里面放内容。再写个显示隐藏事件。够够的了。 Vant的Popup弹出层 页面结构 短短一个背景加内容盒子&#xff0c;vant套了几层。 这是引用的组件…

linux 系统修改已经打好jar包的yml配置文件

工作中可能回遇到&#xff0c;jar包已经打好&#xff0c;并且文件已经上传了&#xff0c;但是突然发现配置文件中的某一个参数写错了&#xff0c;怎么办&#xff1f;重新打包&#xff1f;如果重新打包再上传的话太影响效率了。那么我们可以通过以下方法&#xff0c;修改已经上传…

致远电子冲刺上市:计划募资8亿元,实控人周立功、陈智红已离婚

7月18日&#xff0c;深圳证券交易所披露的信息显示&#xff0c;其已向广州致远电子股份有限公司&#xff08;下称“致远电子”&#xff09;发出第1轮审核问询函。据贝多财经了解&#xff0c;致远电子于2023年6月21日在深圳证券交易所递交招股书&#xff0c;准备在创业板上市。 …

2023最新版本Activiti7系列-事件篇

事件篇 事件&#xff08;event&#xff09;通常用于为流程生命周期中发生的事情建模。事件总是图形化为圆圈。在BPMN 2.0中&#xff0c;有两种主要的事件分类&#xff1a;*捕获&#xff08;catching&#xff09;与抛出&#xff08;throwing&#xff09;*事件。 捕获: 当流程执…

【java】【基础1】数据类型运算符

目录 一、数据类型&#xff08;4大类8种&#xff09; 1.1类型转换 1、自动类型转换 2、表达式的自动类转换 3、强制类型转换 二、运算符 2.1基本算术运算符 2.2自增自减运算符 2.3赋值运算 2.4关系运算符 2.5逻辑运算符 2.6三元运算符 2.7运算符的优先级 三、API文档&am…

中国人民大学与加拿大女王大学金融硕士——行而不辍,履践致远

理论和实践哪个重要呢&#xff0c;申克・阿伦斯曾说过&#xff1a;“如果没有理论的指导&#xff0c;实践就会变得盲目&#xff1b;而如果没有实践的充实&#xff0c;那么理论就会显得空洞”。学习不能停留在理论层面&#xff0c;要用于实践才能真正的消化吸收。学习的目的在于…

第一次实操Python+robotframework接口自动化测试

目前我们需要考虑的是如何实现关键字驱动实现接口自动化输出&#xff0c;通过关键字的封装实现一定意义上的脚本与用例的脱离&#xff01; robot framework 的安装不过多说明&#xff0c;网上资料比较太多~ 实例&#xff1a;&#xff01;&#xff01;&#xff01;&#xff01…

【数学建模】--典型相关分析

典型相关分析&#xff08;Canonical Correlation analysis&#xff09;研究两组变量&#xff08;每组变量中都可能有多个指标&#xff09;之间相关关系的一种多元统计方法。它能够揭示出两组变量之间的内在联系。 例子&#xff1a; 典型相关分析定义&#xff1a; 列题分析&…

visual studio中Git同步提交 报错:管道已结束

这里出现了在提交到远程的时候&#xff0c;vs提示管道已结束。 这里我的解决办法是使用git bash来手动提交 找到仓库的目录&#xff0c;右键找到gitbash的选项&#xff0c;输入add指令来添加文件到暂存区 git add .输入commit指令来将暂存区文件提交到本地仓库 git commit…

内核机制在以下方面发挥作用:

进程间通信&#xff1a;内核提供了特定的机制和接口&#xff0c;用于实现进程间的通信。这可以包括共享内存、管道、消息队列、信号量等。通过这些机制&#xff0c;进程可以在内核的帮助下进行数据传输和同步&#xff0c;实现进程间的协作和通信。 进程调度&#xff1a;内核负…

JAVA集成国密SM2

JAVA集成国密SM2加解密 一、pom配置二、代码集成2.1、目录结构2.2、源码2.3、测试 三、相关链接 国密算法概述&#xff1a;https://blog.csdn.net/qq_38254635/article/details/131801527 SM2椭圆曲线公钥密码算法 为非对称加密&#xff0c;基于ECC。该算法已公开。由于该算法…

详细解析张雪峰老师对计算机专业的评价“进可攻,退可守”--【职场篇】

文章目录 张雪峰的评价计算机行业类的总结性指示就业面宽进可攻&#xff0c;退可守另一个就业出口--培训 持续学习&#xff0c;技术过人 总结 张雪峰的评价 计算机行业类的总结性指示 “就业面宽&#xff0c;进可攻&#xff0c;退可守&#xff0c;各行各业其实对计算机专业都有…

确保安全:选择企业邮箱的五大关键因素!

为您的企业或组织选择正确的邮箱地址可以帮助您确保数据和通信的安全性。不安全的邮箱地址会使您容易受到垃圾邮件、病毒和网络钓鱼攻击。这里有一些小技巧可以帮助你选择一个安全的公司邮箱地址。 1.选择一个你可以信任的邮箱提供商 选择一个安全的公司邮箱地址的第一步是确保…

JavaScript入门——笔记用

JavaScript入门 变量数组常量模板字符串检测数据类型判断分支判断循环数组函数对象 与html和css不同的是js并不是一门标记语言&#xff0c;而是与java等相同&#xff0c;也是一门编程语言&#xff08;实现人机交互的运行在客户端即浏览器的编程语言&#xff09; JavaScript作用…

算法训练营第四十三天||● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零

● 1049. 最后一块石头的重量 II 这道题和昨天的分割等和子集一样&#xff0c;只是最后返回值不一样 class Solution { public:int lastStoneWeightII(vector<int>& stones) {int sum 0;for(int i 0;i<stones.size();i){sum stones[i];}int target sum / 2;…

结构型模式 - 享元模式

概述 定义&#xff1a; 运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似对象的开销&#xff0c;从而提高系统资源的利用率。 结构 享元&#xff08;Flyweight &#xff09;模式中存在以下两种状态&…