如何用语法糖简化(x != null && x.y != null)空值判断
空判断逻辑简化方案
你判断的没错,两种写法并不等价:
当x是实例变量、顶层变量这类可被外部逻辑修改的可变变量时,执行完x?.y != null的判断后,x可能被其他代码重新赋值为null,此时块内的x!.y强制解包依然存在运行时空指针风险,编译器也不会对这类可变变量做自动类型提升。
可以根据使用场景选下面两种标准简化写法,不需要重复写空判断,也完全符合空安全要求:
场景1:代码块内只需要用到
x.y的值,不需要访问x本身
直接用局部变量捕获x?.y的结果,判断非空后直接使用局部变量即可,不需要任何强制解包:final targetY = x?.y; if (targetY != null) { // 此处targetY已被编译器自动提升为非空类型,直接使用即可 ...things that use targetY }这个写法和你最开始的原始逻辑完全等价,没有任何副作用,是最通用的实现方式。
场景2:代码块内需要同时访问非空的
x和x.y
可以在if条件里先把x赋值给不可变的局部变量,再做属性判空,此时局部变量不会被外部修改,编译器会自动完成类型提升:if (final nonNullX = x, nonNullX.y != null) { // 此处nonNullX、nonNullX.y都已被提升为非空类型,不需要强制解包 ...things that use nonNullX.y }
补充说明:如果x是声明后从未被重新赋值的局部变量,编译器可以保证x的值不会在判断后发生变化,此时直接写if (x?.y != null)也会触发自动类型提升,块内可以直接使用x.y不需要加!,和原始逻辑等价。
内容的提问来源于stack exchange,提问作者Serus
相关产品推荐
相关产品推荐

