Java开发中经常要对对象进行非空判断以防止出现空指针。大部分同学都喜欢用下面这种方式来进行判断:
if (obj!=null){
// 判断不等于空
}
if (obj==null){
// 判断等于空
}
这种方式没有什么问题。不过在 Java 7 中专门提供了一个工具类java.util.Objects
可以处理的更好。
java.util.Objects
提供了一系列的静态方法来处理日常一些针对对象的操作。
空值判断
比如开始提到的null
值判断我们可以优化为:
if (Objects.nonNull(obj)){
// 判断不等于空
}
if (Objects.isNull(obj)){
// 判断等于空
}
空值检查
空值检查并不等同于空值判断,空值判断是根据对象是否为空而执行不同的分支策略,而空值检查是要求对象不能为空。为此Objects
提供了如下方法:
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
此方法主要用于在方法和构造函数中进行参数验证,例如:
public Foo(Bar bar) {
this.bar = Objects.requireNonNull(bar);
}
如果你需要自定义抛出空指针信息时可以使用其重载方法requireNonNull(T obj, String message)
:
public Foo(Bar bar, Baz baz) {
this.bar = Objects.requireNonNull(bar, "bar must not be null");
this.baz = Objects.requireNonNull(baz, "baz must not be null");
}
对象比较
一般情况下对象比较我们喜欢使用:
obj.equals(other)
但是并不是每次此方法都能凑效,如果obj
为null
则会抛出空指针异常,因此我们需要对obj
进行前置非空判断。对此Objects
也提供了对应的解决方案:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
但是使用的时候也需要注意一些坑,Objects.equals
在处理基础数据类型和封装类型的比较时会出现一些让人意想不到的问题:
Objects.equals(2,2L)
上面的结果居然是false
! 通过源码发现Objects.equals
在进行比较时会自动对基本类型做封装,也就是说它把2
封箱为Integer
,2L
封箱为Long
,类型不同自然为false
。
尽量保证Objects.equals
的两个对象类型一致。
对象深度比较
Objects
中还有一个deepEquals
方法,此方法的功能比较强大,不仅可以比较对象是否相同,如果该对象是数组还可以比较内容是否相同,但是胖哥并不常用。
其它方法
Objects
也对hash
、toString
以及对两个对象进行比较的方法(Comparator
)compare
的封装,其中也涉及了对空的处理,不过这几个方法确实不太常用,有兴趣的可以去研究一下。