Kotlin学习之空安全

作者: 程序员丶星霖 | 来源:发表于2017-12-01 08:50 被阅读132次

Kotlin学习之空安全

Kotlin相对于Java有许多改良的地方,空安全就是其中的一部分,Kotlin因此解决了空指针问题。

一、空安全

Java语言中没有C/C++的指针,取而代之的是引用。在Java支持的四种数据类型(类、接口、数组、基本类型)中,类、接口和数组统称为引用类型,定义一个引用类型变量需要两个步骤:

  1. 定义一个引用类型的变量。
String s;
List<String> l;
int[] n;
  1. 进行初始化(创建对象并使之前定义的引用指向这个对象)。有两种方法:
  • 用new关键字调用构造方法,创建一个新对象;
  • 使用方法出入一个对象。
s = "Hello World"; // String 类型的特殊写法,等同于调用构造方法
l = new ArrayList<>(); // 使用子类型创建对象
n = new int[10];

在Java中,对于没有进行初始化的引用类型变量,调用它们的实例方法或实例属性都会产生NullPointerException,也就是所谓的NPE。而这一切都发生在运行时,编译时不会报错

Kotlin的类型系统诣在从代码中消除NullPointerException。NPE的唯一可能的原因是:

  • 显示调用throw NullPointerException();
  • 使用了下文描述的!!操作符;
  • 外部Java代码导致的;
  • 对于初始化,有一些数据不一致。

Kotlin解决空安全,而不是消灭NPE,而是允许NPE存在,但只会在它该出现的时候出现。Kotlin区分了可空类型不可空类型

二、可空类型与非空类型

在Kotlin中如下代码:

val s: String = null

会得到一个编译错误。编译器说不能讲null赋给非空的String类型。

在Kotlin中,所有数据类型默认都是非空的,如果想把null赋给它们的对象,需要在类型后加上?,声明为可空类型。

所以上面的代码需要在String后面加上?:

val s: String? = null

所以,在Kotlin中我们只要将变量声明为非空类型,就可以放心地调用它的实例方法和实例变量,不用担心出现NPE。

三、安全调用符(?.)

对于可空类型的变量,应该怎样安全地调用它的属性和方法呢?Kotlin的解决方式是使用?.安全调用符。

如下面Kotlin的函数:

// 安全调用属性
fun printLengthOfString(s: String?) = println(s?.length)

在Java中等同于如下:

public static final void printLengthOfString(@Nullable String s) {
  Integer var1 = (s != null) ? s.length() : null;
  System.out.println(var1);
}
  • 安全调用操作符(?.)实际上是个语法糖,会被编译为一个三目运算表达式。
  • 如果?.前的对象不为null,则调用?.后的方法或属性,否则就返回null。
  • 如果一个可空变量已经被判断为非空,再次调用它的方法和变量时,会自动将变量转换为非空类型,实现安全调用。

四、Elvis操作符(?:)

这个操作符是三目条件运算符的简略写法。

如果?:左侧表达式非空,Elvis操作符就返回其左侧表达式,否则就返回右侧表达式。请注意,当且仅当左侧为空时,才会对右侧表达式求值

Kotlin中用Elvis操作符配合安全调用符实现简单清晰的空检查和空操作。

在Java中:

(files != null) ? files.length : "Empty"

在Kotlin中:

files?.size ?: "Empty"

可以如下理解Elvis操作符:

  • A ?: B 等价于 if(A==null) B
  • A ?. B ?: C 等价于 if(A!=null) A.B else C

五、let函数

let函数可以看做一个加强版的安全操作符,或者另一种写法if not null then语句。

let函数单纯地接收一个函数,然后执行它,返回函数的执行结果。一般情况下,let函数与安全调用符配合使用:

val listWithNulls: List<String?> = listOf("A", null)
for (item in listWithNulls) {
     item?.let { println(it) } // 输出 A 并忽略 null
}

也就是时候安全调用符+let函数就等同于if not null then语句。

六、非空操作符(!!)

要在Kotlin中产生NPE,有两种办法:

  • 显式地throw NullPointerException();
  • 使用非空操作符!!。
val l = b!!.length

b!!会返回一个非空的b值,如果b为空,就会抛出一个NPE异常。

但是,Kotlin并不建议在代码中广泛使用!!操作符,因为这样会浪费Kotlin良好的非空类型的设计,让Kotlin代码中充斥着NPE。

学海无涯苦作舟

我的微信公众号.jpg

相关文章

  • Kotlin学习之空安全

    Kotlin学习之空安全 Kotlin相对于Java有许多改良的地方,空安全就是其中的一部分,Kotlin因此解决...

  • Kotlin学习之空安全

    可空类型与非空类型 Kotlin 的类型系统旨在消除来自代码空引用的危险,也称为《十亿美元的错误》。许多编程语言(...

  • Android开发kotlin学习(二)

    1.kotlin的空安全 为啥子说kotlin是空安全的?和Java相比,kotlin的空安全可以带来哪些便利之处...

  • Kotlin 之空安全

    背景 在 Java 语境下,使用对象总是让我感到明显的不安全感,这个对象要判空吗?这个对象肯定不会为空,不用加判断...

  • Kotlin - 空安全

    1.Kotlin空安全介绍 Kotlin空安全可消除来自代码空引用的危险。 2.什么是空引用? 许多编程语言(包括...

  • Kotlin学习笔记-[空安全]

    前言 kotlin是如此的令人激动,在语法层面上就杜绝了程序中最常出现的,最令人厌恶的空指针异常。 可空与非空类型...

  • 2017-07-18-kotlin Android基础

    kotlin Android基础 1,实现一个基本的数据类 2,空安全: Kotlin,如很多现代的语言,是空安全...

  • Kotlin学历之空安全

    简述 在java中Null是最常见的陷阱之一,在很多时候不得不写非空判断来增加代码的安全性,随着业务的增长,非空的...

  • kotlin学习--可空类型,空安全

    在我们熟知的Java中,定义一个变量可以默认不赋值,因为Java的系统会给我们默认赋一个默认值,并且Java可定义...

  • Kotlin null 检测机制、空安全、空指针问题

    空安全 Kotlin 引入可空类型、非空类型 Kotlin 的类型系统旨在消除来自代码空引用的危险 许多编程语言(...

网友评论

本文标题:Kotlin学习之空安全

本文链接:https://www.haomeiwen.com/subject/radibxtx.html