NullPointException 是 Android 开发中最常见,也最容易 fix 的异常之一。每当发生 NullPointException 时,解决方案大多都是根据错误堆栈,获取错误行数,然后加个 if (someObject != null)
的判断。看似简单的 fix,实际开发中,我们也不可能会对每个需要使用的 Object,进行非空判断,这样会导致代码十分冗余,而且,这样做,有些非空判断,可能永远都是返回 true. 除了给代码添加行数外,也没什么实际意义。
所以,问题的关键是,要辨别对象是否可能为空,然后给可能为空的变量进行非空判断。下面总结了几种策略来帮我们处理辨别对象是否为空的情况。
1、@Nullable
@Nullable 是 Java的一个注解,可以对成员变量,方法,以及方法参数进行修饰。分别对应成员变量、方法返回值、方法参数可能为空。调用者在使用这些变量、方法时,应该进行非空判断。借助 Android Studio IDE,如果使用前没有进行非空判断,IDE 会有一个 warning,提醒进行非空判断。相应的还有一个 @Nonnull 注解,修饰范围和 @Nullable 一样,标记变量或者返回值不可能为空,调用方无需进行非空判断。
2、命名约定
通过命名约定来变量、返回值可能为空的情况,比如,nullableDate,nullableString, getNullableVersionName(),调用方根据方法名、变量名,判断是否需要非空判断。
3、Optional\
Optional\
1 | public class Optional<T> { |
4、 防御性编程
其实上面任何一条都不是完美的,因为我们无法做到整个项目都遵循这些策略,毕竟我们的项目底层依赖 SDK,还引用了大量第三方 framework,简称别人的代码,这些别人的代码,是如何处理非空问题的,大多都没有遵循以上任意一条,我们也就无法通过一些约定来进行处理判断。此时,不要相信任何外界输入输出。在使用第三方方法、网络数据时,多个心眼,多加判断,往往是利大于弊。
我们在写 library 时,要考虑别人传来的参数的可能情况,做好防御。给别人返回值时,集合类返回 emptyList/emptyMap,数组返回 0 长数组。