equals方法
Object类中的equals 方法在非空对象引用上实现相等关系,具有对称性a.equals(b) 和 b.equals(a) 结果是一样的,但当a == null时会抛出空指针异常
import java.util.Objects;
String a=null;
String b="";
System.out.println(a.equals(b));//异常
我们可以通过使用如下的方式来规避掉这个问题
String a=null;
String b="";
System.out.println(b.equals(a));
但是,使用这种方式的前提是,我们非常的清楚的知道某一个参与比较的值,一定不为空,但是有时候,我们不确定参与比较的值是否为空,假如都为空的话,那么仍然可能会报空指针异常。
这个时候就需要使用Objects中的equals方法来比较
String a = null;
String b = null;
System.out.println(Objects.equals(a, b));
使用这种方式,即使a或者b都是空的,仍然不会出现空指针,可以巧妙的避开空指针。
Objects中的equals方法,源代码如下:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
可以比较两个基本数据类型的数值是否相等,而equals方法依旧调用的是Object对象中的方法,比较俩个Object对象的地址值是否引用的同一块地址,如果不同则为false
而Objects还有一个名为deepEquals的方法,功能比较强大,不光能比较两个基本类型是否相等,还能够比较两个对象的内容是否相同,所以比较两个对象的内容是否相同的时候,我们应该使用deepEquals方法。
源代码如下:
public static boolean deepEquals(Object a, Object b) {
if (a == b)
return true;
else if (a == null || b == null)
return false;
else
return Arrays.deepEquals0(a, b);
}
static boolean deepEquals0(Object e1, Object e2) {
assert e1 != null;
boolean eq;
if (e1 instanceof Object[] && e2 instanceof Object[])
eq = deepEquals ((Object[]) e1, (Object[]) e2);
else if (e1 instanceof byte[] && e2 instanceof byte[])
eq = equals((byte[]) e1, (byte[]) e2);
else if (e1 instanceof short[] && e2 instanceof short[])
eq = equals((short[]) e1, (short[]) e2);
else if (e1 instanceof int[] && e2 instanceof int[])
eq = equals((int[]) e1, (int[]) e2);
else if (e1 instanceof long[] && e2 instanceof long[])
eq = equals((long[]) e1, (long[]) e2);
else if (e1 instanceof char[] && e2 instanceof char[])
eq = equals((char[]) e1, (char[]) e2);
else if (e1 instanceof float[] && e2 instanceof float[])
eq = equals((float[]) e1, (float[]) e2);
else if (e1 instanceof double[] && e2 instanceof double[])
eq = equals((double[]) e1, (double[]) e2);
else if (e1 instanceof boolean[] && e2 instanceof boolean[])
eq = equals((boolean[]) e1, (boolean[]) e2);
else
eq = e1.equals(e2);
return eq;
}
toString()方法和valueOf()
很多时候为了图方便,需要将某个对象转换为String的时候都是直接调用对象的toString()方法,可是这样有个问题,当那个对象是null的时候,再调用toString()方法又会带来空指针问题,我们这个时候,就应该使用valueOf()来进行转换
Double d = null;
System.out.println(String.valueOf(d));
System.out.println(d.toString());// 异常
Optional
因为有时候,我们可能会出现链式调用的情况,比如
school.getMajor("计算机").getTeacher().getName();
为了避免空指针,我们需要不断的if,如果调用的层次越多,那么if的嵌套就会越深,上面的那段代码就会变成如下这样
if (school!=null) {
Major major=school.getMajor("计算机");
if (major!=null) {
Teacher teacher=major.getTeacher();
if (teacher!=null) {
String name=teacher.getName();
}
}
}
因为个人原因,我觉得这样非常的不美观,不和谐,为了避免空指针,没有办法。不过,现在有了新的方法来解决这个问题,上面的代码就可以改写成如下
String name=Optional.ofNullable(school)
.map(school -> school.getMajor("计算机"))
.map(Teacher::getName)
.orElse("Not Find");
这样,就可以保证在链式调用的时候,不会出现空指针,以为根据定义,Optional是一个可能存在也可能不存在的值,我们可以通过他的ifPresent方法去判断对象中是否存在值,通过orElseThrow方法,在没有值的时候直接甩出异常等等
就想到这么多,后续想到了再来补充