科普文:Java的 Optional 处理空指针弱爆了,看看隔壁 Kotlin 才是真优雅
CSDN的小伙伴,大家有没有吃晚饭。我是编哥、也可以叫我编编哥
咱组里两个码农因为Java8的Optional到底是不是脱裤子放屁的友好讨论(ji lie si bi),最后谁也没能说服谁。编哥最后留下一句Java的判空都弱爆了,都给我去学学Kotlin
正好最近看到不少大佬也在讨论这事,还有类似“用Optional优雅地处理空判断”之类的文章。
今天编哥也不打算让大家就开始去学 Kotlin,咱只是了解一下 Kotlin 如何避免 NullPointerException
,至少就不必再去纠结用不用 Optional 了,反正也就那样。嗯,仅仅是科普~
先说点题外话
Kotlin 每行代码后面不用加分号;
,new对象不用写new
,声明变量可以不用写类型var nice = true
,爽翻~
上代码
Java 里为了避免 NullPointerExceptioin
,我们常常会写一堆if-else
。比如这种情况,取一个用户的地址信息:
if (user != null
&& user.getLocation() != null
&& user.getLocation().getAddress() != null)
&& user.getLocation().getAddress().getStreet() != null) {
return user.getLocation().getAddress().getStreet();
} else {
// 为空处理
}
但用 Kotlin 会是啥样呢?
return user?.location?.address?.street?: "地址为空"
是的,只需一行,还能给一个为空的默认值。优雅吧~
如果遇到复杂一些的情况,比如每种情况要做不同处理,Java 搞不好代码就成这样了:
if (user != null) {
if (user.getLocation() != null) {
if (user.getLocation().getAddress() != null) {
if (user.getLocation().getAddress().getStreet() != null)
return user.getLocation().getAddress().getStreet();
} eles {
// street 空处理
}
} else {
// address 空处理
}
} eles {
// location 空处理
}
} else {
// user为空处理
}
用Optional改造后会优雅不少,但看上去还是怪怪的。不信你看:
Optional<User> optionalUser = Optional.ofNullable(user);
String street = optionalUser
.flatMap(u -> Optional.ofNullable(u.getLocation()))
.flatMap(l -> Optional.ofNullable(l.getAddress()))
.map(Address::getStreet)
.orElse("Unknown");
System.out.println("Street: " + street);
另外,用kotlin处理需要if-else的空值,也简便得多。比如上面那种java的处理,用kotlin对应就是:
user?.location?.address?.street?.apply {
log.d("get user street info $this")// street 不为空,这里就能用this代表street了
} ?: run {
log.d("user street not set")// 这里就处理street 为空的情况
}
怎么样,不用写一堆if判断,简简单单就能把if-else替换掉了吧。
上面这种如果处理空和非空的处理都只有一行,可以把整个语句都简化到一行:
user?.location?.address?.street?.apply { log.d("get user street info $it") } ?: run { log.d("user street not set") }
而且在Kotlin中,这样的判空的成本很低,基本就是在声明变量的时候加个问号?
就行了:
var user: User? // 加了问号就是可空类型
var localUser: User = createUser()//不加问号,就是非空,必须有初始化,而且中间值改变的时候也不能赋可能是空的值
总结
Kotlin相对于Java的空值处理有以下优势:
-
代码简洁性: Kotlin的可空性使得代码更加简洁和易读。不再需要显式的条件检查和Optional,这减少了代码的复杂性。
-
减少空指针异常: Kotlin的可空性减少了空指针异常的发生,因为它在编译时能够识别潜在的空值访问,并提供了安全的调用和默认值选项。
-
类型推断: Kotlin的类型推断机制可以正确地处理可空类型,这意味着开发者无需过多地注明变量的类型。
-
与Java互操作性: Kotlin可以与Java代码无缝互操作,因此可以逐步迁移项目而无需全面重写代码。
再多说两句
虽然 Kotlin 就是 Idea 的厂商JetBrain
发明的,可能很多 Javaer 还不知道。但国内Kotlin目前主要在安卓开发流行。Java开发方面,用也只会把 Kotlin 用在一些个人试验项目或公司新的独立小项目上。
不过只要用惯Kotlin都会嫌弃Java的“蹩脚”,相信以后用Kotlin的也会慢慢多起来。
不过,咱再看看zhihu上这些大神的回答,好吧,当我啥也没说~[捂脸]