Java中,比较两个不同类型的包装类型时候,即使数值相等,使用equals方法也会返回false
示例:
public static void main(String[] args) {
System.out.println(Objects.equals(1L, 1));
System.out.println(Long.valueOf(1L).equals(1));
System.out.println(Integer.valueOf(1).equals(1L));
}
结果:
从源码分析原因
java.lang.Long#equals
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
java.lang.Integer#equals
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
java.util.Objects#equals
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
其他数字类型源码暂不贴出。
从源码看出,包装的数字类型,使用equals方法的前提必须是:类型一致。
如果原生类型存在自动类型转换,或原生类型与包装类型混用比较,很容易导致bug的发生。
如何避免
除了类型转换成一致使用equals方法,数字类型比较使用compare方法。
示例:
public static void main(String[] args) {
System.out.println(Objects.compare(1, 1,Integer::compareTo));
System.out.println(Objects.compare(1L, 1L,Long::compare));
int a = 1;
Long b = 1L;
System.out.println(Long.compare(a,b));
System.out.println(Integer.compare(a, Math.toIntExact(b)));
}
结果:
小结
Java中,比较两个不同类型的包装类型时候或原生类型和包装类型混用,即使数值相等,使用equals方法也会返回false。
封装的数字类型,使用equals方法的前提必须是:类型一致,我们必须类型转换成同一类型。
数字类型比较最好使用compare方法。