一、前言

<font face= 黑体>在 Kotlin 中的类与接口 中咱们曾经讲了 Kotlin 的 接口扩大办法,明天咱们来讲 Kotlin 中的 空类型平安智能类型转换

二、Kotlin 空类型平安

2.1、空类型平安概念

<font face= 黑体>Java 语言中是没有空类型平安这一概念的,所以写 Java 代码常常会呈现空指针异样,然而 Kotlin 致力于打消空援用所带来的危险,所以就有了空类型平安概念。

<font face= 黑体>上面这段代码在 Kotlin 中是无奈编译通过的,因为 Kotlin 的 String 是不能承受空值的,所以这个赋值操作是不被容许的。

var nonNull: String = "Hello"nonNull = null  // 不可空类型,不能赋值为 null// 拜访长度的话,不须要空判断val length = nonNull.length

<font face= 黑体>IDE 报错如下所示:

<font face= 黑体>然而如果咱们非得定义一个空值,也是有方法的,Kotlin 为了 100% 兼容 Java,必须得实现接管空值,所以要接管空值能够在定义的时候加一个 ?。

<font face= 黑体>然而这个时候这个变量就可能是空值,所以拜访的时候就会比拟严格,比方上面代码中的 nullable.length 就会报错,因为可能触发空指针异样。

var nullable: String? = "Hello"nullable = null  // 可空类型,编译通过val length = nullable.length // 可能触发空指针,编译保报错

<font face= 黑体>IDE 报错如下所示:

<font face= 黑体>这个时候咱们想 nullable.length 不报错能够:

  1. <font face= 黑体>当咱们确定 nullable 不可能为空的时候,能够将 nullable 强转为不可空类型,如下所示:

    var nullable: String? = "Hello"// 不会报错了(本人曾经晓得了,这个 nullable 不可能为空)val length = nullable!!.length 
  2. <font face= 黑体>如果咱们不确定 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、空类型的继承关系

<font face= 黑体>咱们晓得 Int 是 Number 的子类,所以通过上面的代码咱们就能够晓得 String 应该是 String? 的子类。
var a: Int = 2var b: Number = 10.0a = b // Type mismatch,报错b = a // OKvar x: String = "Hello"var y: String? = "World"x = y // Type mismatch,报错y = x // OK

2.3、Kotlin 空类型平安回顾

三、Kotlin 智能类型转换

3.1、智能类型转换例子

<font face= 黑体>例子1:

<font face= 黑体>咱们先来写一个 Java 的类型转换:

// 定义一个接口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);  // 正确写法        }    }}

<font face= 黑体>同样的代码在 Kotlin 中就能够实现智能类型转换,不须要强制类型转换:

val kotliner: Kotliner = Person("Test", 20)if (kotliner is Person) {    println((kotliner as Person).name)  // 不须要强转,能够智能转换,所以上面的写法就能够了    println(kotliner.name)}

<font face= 黑体>例子2:

<font face= 黑体>上面这段代码定义了一个 value, 类型是 String?,if 判断其不为空,所以在 if 判断这个括号外面,value 的类型会被智能转换成 String,当然出了括号,value 的类型就又是 String? 了。
var value: String? = nullvalue = "Test"if (value != null) {    // value: String?  ==>  String    println(value.length)}// value: String?...

3.2、不反对智能类型转换的状况

<font face= 黑体>上面这种状况就不反对智能类型转换,因为这个公共变量很多中央都能够拜访,所以咱们在判断不为空之后,有可能别的线程又把 tag 改成了空,所以这种状况智能类型转换就生效了。
// 在 main 函数之外定义一个公共变量var tag: String? = nullfun main() {    if(tag != null) {        // 有可能被改成空        println(tag.length)  // 报错,不反对智能类型转换    }}

3.3、几个倡议

  • <font face= 黑体>尽可能应用 val 来申明不可变援用,让程序的含意更加清晰确定;
  • <font face= 黑体>尽可能减少函数对外部变量的拜访;
  • <font face= 黑体>必要的时候曾创立局部变量指向内部变量,防止因它变动引起程序谬误。

3.4、Kotlin 智能类型转换

四、小结

<font face= 黑体>本篇博客次要讲了 Kotlin 中的空类型平安智能类型转换,下一节咱们讲 Kotin 中的表达式

五、源码

源码 已上传至 github,有须要能够间接下载。