写一篇关于NPL的技术文章为了帮助我总结,避免了大量浪费时间处理这种的常见问题。最近我做了很多项目经常会碰到的“噩梦”之一就是NullPointerException(NPE),因为Java允许变量为null,而在调用对象方法或属性时未做null检查,就会抛出NPE。这种情况在Kotlin里几乎不再是问题,因为Kotlin从语言层面引入了空安全支持,彻底减少了NPE的出现概率。下面我们看看两种语言是如何应对NPE的,通过示例展示常见的编程场景。
几乎所有对象都可以为null,意味着我在调用任何方法时,都需要小心检查对象是否为空。例如,以下代码会抛出NPE,因为 a可能为null:
int getStringLength(String a) {
return a.length(); // 如果a是null,就会抛出NPE
}
可以在调用方法前手动检查null值避免NPE:
int getStringLength(String a) {
return a != null ? a.length() : 0;
}
Java 8引入了Optional
类,提供一种更优雅的null处理方式。下面的代码使用了Optional
类:
Optional<String> optionalString = Optional.ofNullable(a);
int length = optionalString.map(String::length).orElse(0);
所有类型默认都是不可空的,除非特意用?
标记它是可空的。这样,Kotlin可以在编译时帮助我们捕捉潜在的NPE,而不是等到代码运行时才发现。比如:
fun getStringLength(a: String): Int = a.length // 编译时检查,a不能为null
如果希望变量可以为空,那么可以将类型声明为String?(带?表示可空)
,表示它可以保存null
值:
fun getStringLength(a: String?): Int = a?.length ?: 0
在上面的代码中,a?.length
是一种安全调用写法(?.
),它的作用是如果a
为空就返回null,而不是抛出异常。?:
称为Elvis操作符,它为null的情况指定一个默认值。这样代码是很安全又简洁,非常适合日常开发中使用。
Elvis操作符(?:
)可以在变量为null时提供默认值。举例子,在找一个订单,但找不到时希望返回默认订单对象,就可以这么写:
val order = findOrder() ?: Order(Customer("默认客户"))
这段代码的意思是:如果findOrder()返回的订单是null,就用一个默认的订单代替。相比Java中的if-else空检查,这样的写法很简单、易读。
Kotlin 和Java 可以互相调用,但Java代码没有空安全检查,会让Kotlin这些类型为“平台类型”。平台类型没有空安全约束,可当作可空类型也可当作非空类型,这意味着Kotlin不会强制检查null,但使用Java代码时一定要小心,确保不会触发NPE。例如:
val customer = javaMethodThatReturnsNullableCustomer()
println(customer?.name ?: "未找到客户")
这种情况下,Kotlin调用Java方法时不会做null检查,需要在使用平台类型变量前加上安全调用(?.
),避免意外的NPE。
在Java中,类型转换通常借助instanceof
判断变量类型,确保转换安全。Kotlin则提供了as?
操作符,用于安全类型转换。如果转换失败,它会返回null而不是抛异常。这种设计避免了强制类型转换带来的风险:
fun getStringLength(y: Any): Int {
val x: String? = y as? String
return x?.length ?: -1
}
这段代码意思是:尝试将y
转换为String
,如果转换失败就返回null。配合?.
使用,为了很轻松编写安全代码。
综上总结,Kotlin通过编译时的空检查、可空类型支持和安全调用等功能,几乎不会发生了NPE的发生。Java虽然引入了Optional
类解决空值问题,但整体语法很繁琐。而Kotlin将空安全直接融入类型系统,不需要额外操作即可避免NPE。
在日常开发中,Kotlin让代码更流畅、更安全,从Java转向Kotlin的开发者可以充分体验到空安全特性的便捷,减少了处理空值所带来的麻烦。这些空安全特性不仅让开发更高效,也让代码更健壮
谢谢大家阅读)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。