记一次故障

上周发生了一次故障,新手任务中的首购理财没有成功。原因很简单,错误地使用了java中的equals方法T^T。

这是java.lang.Long的equals源码。
1
2
3
4
5
6
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).intValue();
}
return false;
}

而这次故障的原因是我把一个Long对象和Integer对象用equals进行比较。
关于 == 与 euqlas的选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public static void main(String args[]) {
Long aLong = 10086L;
Long bLong = 10086L;
Integer aInt = 10086;
Integer bInt = 10086;
int a = 10086;
int b = 10086;
long al = 10086L;
long bl = 10086L;
// 包装类型与包装类型比较,原生类型与原生类型比较
System.out.println("aLong == bLong is " + String.valueOf(aLong == bLong));
System.out.println("aInt == bInt is " + String.valueOf(aInt == bInt));
System.out.println("a == b is " + String.valueOf(a == b));
System.out.println("al == bl is " + String.valueOf(al == bl));
System.out.println("aLong.equals(bLong) is " + String.valueOf(aLong.equals(bLong)));
System.out.println("aInt.equals(bInt) is " + String.valueOf(aInt.equals(bInt)));

// 同样的精度不同类型比较
System.out.println("aLong == al is " + String.valueOf(aLong == al));
System.out.println("aInt == a is " + String.valueOf(aInt == a));
System.out.println("aLong.equals(al) is " + String.valueOf(aLong.equals(al)));
System.out.println("aInt.equals(a) is " + String.valueOf(aInt.equals(a)));

// 不同精度同样类型比较
// System.out.println("aLong == aInt is " + String.valueOf(aLong == aInt)); 编译错误
System.out.println("al == a is " + String.valueOf(al == a));
System.out.println("aLong.equals(aInt) is " + String.valueOf(aLong.equals(aInt)));

// 不同精度不同类型
System.out.println("aLong == a is " + String.valueOf(aLong == a));
System.out.println("aInt == al is " + String.valueOf(aInt == al));
System.out.println("aLong.equals(a) is " + String.valueOf(aLong.equals(a)));
System.out.println("aInt.equals(al) is " + String.valueOf(aInt.equals(al)));
}

执行结果是这个样子的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
aLong == bLong is false
aInt == bInt is false
a == b is true
al == bl is true
aLong.equals(bLong) is true
aInt.equals(bInt) is true
aLong == al is true
aInt == a is true
aLong.equals(al) is true
aInt.equals(a) is true
al == a is true
aLong.equals(aInt) is false
aLong == a is true
aInt == al is true
aLong.equals(a) is false
aInt.equals(al) is false

总结一下:

  • 只要有原生类型参与的比较,都用 “==”。(只要有原生类型参与,那么就会有自动拆箱的操作)
  • 如果是精度相同用equals。(Long和long,Integer和int)
  • 如果精度不相同,也没有原生类型参与,那么应该这么写:l == null ? i == null : ObjectUtils.equals(l.intValue(), i)。

PS: 其实我觉得以后不用int和Integer类型,全部都用Long和long可以避免踩这个坑。