思维导图|kotlin NPE方案

大家好,我是青空。今天给大家带来的是kotlin NPE方案。

图片

文末可领取大厂面试题

NPE的来源

显式调用 throw NullPointerException()

使用了 !! 操作符

  • 这是Kotlin提供的用户可强制抛出NPE的操作符

  • 使用了!!只要碰到NPE就会如期抛出

有些数据在初始化时不一致

  • this泄漏

  • 未初始化的this被传递,并用于其他地方

  • 调用了一个 超类中的open成员,并在 派生类中使用了 该open成员的未初始化 状态

Java 互操作

  • 企图访问平台类型的 null 引用的成员

  • 平台类型 即 Java 声明的类型

  • java的引用可能是null

  • 平台类型的范例

val list = ArrayList<String>() // 非空(构造函数结果)
list.add("Item")
val size = list.size // 非空(原生 int)
val item = list[0] // 推断为平台类型(普通 Java 对象)
item.substring(1) // 允许,如果 item == null 可能会抛出异常

  • 具有错误可空性的 Java 互操作的泛型类型

  • 真是绕口,怎么理解呢

  • 从java代码中向Kotlin添加了一个null值到MutableList

  • MutableList无法处理null

  • 自然这个null需要MutableList<String?>处理

  • 由外部 Java 代码引发的其他问题

如何区分类型系统是否容忍null

范例

fun main() {
    var a: String = "abc"
    a = null // 编译错误
}

若 a 声明为String!  则 可为空

fun main() {
    var b: String? = "abc"
    b = null // ok
    print(b)
}

  • 访问 val l = a.length

  • 这就不会报错

  • 访问val l = b.length // 错误:变量“b”可能为空

  • 编译器会报错

在条件中检测 null

这就是用if …else进行判空

范例

val l = if (b != null) b.length else -1

安全的调用

操作符,写作 ?.

会议一下java的网络请求返回的实体

  • 在java中是这样的

  • 只要有一个环节为null就报npe

  • bob.department.head.name

  • 在Kotlin中可以这样

  • 任一环节为null,就会返回 null

  • bob?.department?.head?.name

如果要只对非空值执行某个操作

  • 可以与 let 一起使用 范例
fun main() {
    val listWithNulls: List<String?> = listOf("Kotlin", null)
    for (item in listWithNulls) {
        item?.let { println(it+" is the result") } // 输出 Kotlin 并忽略 null
    }
}

输出

Kotlin is the result

赋值过程中的安全调用

范例

// 如果 `person` 或者 `person.department` 其中之一为空,都不会调用该函数:
person?.department?.head = managersPool.getManager()

在这里范例中,只要左侧返回null,就跳过右侧表达式的求值

注意

不要在右侧表达式做过多的处理,尽量纯净,小心处理会依赖这部分逻辑的操作,避免埋坑

Elvis 操作符

当我们有一个可空的引用 r 时,我们可以说“如果 r 非空,我使用它;否则使用某个非空的值 x”

一般是这样写的

val l: Int = if (r != null) r.length else -1

通过 Elvis 操作符表达

  • 写作 ?:

  • 这个表达式,就可以改写为

  • val l = r?.length ?: -1

  • ?: 左侧表达式非空,?:   (elvis 操作符)就返回其左侧表达式,否则返回右侧表达式

  • 注意

  • throw 和 return 在 Kotlin 中都是表达式

  • 在表达式中也支持throw和return

范例

fun foo(node: Node): String? {
    val parent = node.getParent() ?: return null
    val name = node.getName() ?: throw IllegalArgumentException("name expected")
    // ……
}

!! 操作符

如果你想要一个 NPE

  • 你必须显式要求它

就用到!!操作符

范例

val l = b!!.length
b为null的话,就会强制抛出NPE

安全的类型转换

对象不是目标类型

  • 常规类型转换可能会导致 ClassCastException

可以选择as?

  • 进行安全类型转换
val aInt: Int? = a as? Int

转换不成功则返回 null

可空类型的集合

你有一个可空类型元素的集合

  • 你想要过滤非空元素

可以使用 filterNotNull

范例

val nullableList: List<Int?> = listOf(1, 2, null, 4)
val intList: List<Int> = nullableList.filterNotNull()

最近又赶上跳槽的高峰期,好多粉丝,都问我有没有最新大厂面试题,我连日加班好多天,终于整理好了,1000+ 道,20多份大厂面试题大全,我会持续更新中!公众号回复【面试题】即可获取。

图片

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值