Talk is cheap, I’ll show you the code.
package tmp;
import java.util.Objects;
/**
* @Author : zs.sun
* @Date : 2018/9/19 20:32
* @Package : tmp
* @ProjectName: java
* @Description: 最近编写的房态房价处理过程中,会出现一些空指针,或者比较错误。
* 现在将整数比较进行一次整理。
*/
public class Test {
// 2 等价于 smallInt的情况 2000 等价于 bigInt的情况 不再单独测试
private static int smallInt=2;
private static int bigInt=2000;
private static Integer smallIntClass=2;
private static Integer bigIntClass=2000;
private static short smallShort=2;
private static short bigShort=2000;
private static Short smallShortClass=2;
private static Short bigShortClass=2000;
private static Integer sameSmallIntClass=2;
private static Integer sameBigIntClass=2000;
private static Short sameSmallShortClass=2;
private static Short sameBigShortClass=2000;
public static void main(String[] args) {
test();
}
/**
* 对整数进行比较大小,进行总结
* 同值同类型的不进行测试比较,因为必然相等。
* PS: 对于== 会提一下比较逻辑。
*/
// Note: To the same class with the same value, they are the same
private static void test()
{
// //测试equals()方法
// testEquals();
// //测试Objects.equals()方法
// testObjectsEquals();
// //测试==比较
// testEqualOperation();
// 测试存在null情况下的整数比较情况
testEqualExistNull();
}
/**
* 对于equals()比较,
* 注意点
* 1. 调用者必须为类型,且不为空指针。
* 2. 对于Short.equals(int/Integer),Integer.equals(short/Short)肯定false
* 其他情况与正常意义上的比较情况相同
*/
public static void testEquals()
{
boolean b1 = smallIntClass.equals(smallShort); // false
boolean b2 = smallIntClass.equals(smallShortClass); // false
boolean b3 = smallIntClass.equals(smallInt); // true
boolean b4 = bigIntClass.equals(bigShort); // false
boolean b5 = bigIntClass.equals(bigShortClass); // false
boolean b6 = bigIntClass.equals(bigInt); // true
boolean sb1 = smallShortClass.equals(smallInt); // false
boolean sb2 = smallShortClass.equals(smallIntClass); // false
boolean sb3 = smallShortClass.equals(smallShort); // true
boolean sb4 = bigShortClass.equals(bigInt); // false
boolean sb5 = bigShortClass.equals(bigIntClass); // false
boolean sb6 = bigShortClass.equals(bigShort); // true
System.out.println();
}
/**
* 对于Objects.equals()比较
* 注意点:
* 1. 同类型的比较,值相等,必然相同
* 2. 对于Objects.equals(int/Integer, short/Short)必然为false
* 3. 对于Objects.equals(int, Integer), Objects.equals(short, Short)相等为true,不等为false
*/
public static void testObjectsEquals()
{
// Note: To the same class with the same value, they are the same
boolean b1 = Objects.equals(smallInt, smallShort); // false
boolean b2 = Objects.equals(smallInt, smallShortClass); // false
boolean b3 = Objects.equals(smallInt, smallIntClass); // true
boolean b4 = Objects.equals(smallIntClass, smallShort); // false
boolean b5 = Objects.equals(smallIntClass, smallShortClass); // false
boolean b6 = Objects.equals(smallShort, smallShortClass); // true
boolean bigB1 = Objects.equals(bigInt, bigShort); // false
boolean bigB2 = Objects.equals(bigInt, bigShortClass); // false
boolean bigB3 = Objects.equals(bigInt, bigIntClass); // true
boolean bigB4 = Objects.equals(bigIntClass, bigShort); // false
boolean bigB5 = Objects.equals(bigIntClass, bigShortClass); // false
boolean bigB6 = Objects.equals(bigShort, bigShortClass); // true
System.out.println();
}
/**
* 对于==进行比较,
* 注意点:
* 1. 同类型的比较,值相等,可能不等。基本整数类型,必然相等。对于包装器需要其值在[-128, 127)范围之内
* 2. 对于int/short == int/short/Short/Integer 这种类型的比较,相等为true,不等为false。
* 3. 对于Short == Integer, 类型无法比较
* 4. 对于Short == Short, Integer == Integer这种情况,注意常量池的使用情况就行。
*/
public static void testEqualOperation()
{
boolean b1 = smallInt == smallShort; // true
boolean b2 = smallInt == smallShortClass; // true
boolean b3 = smallInt == smallIntClass; // true
boolean b4 = smallIntClass == smallShort; // true
// boolean b5 = smallIntClass == smallShortClass; // bug, cannot run
boolean b6 = smallShort == smallShortClass; // true
boolean bigB1 = bigInt == bigShort; // true
boolean bigB2 = bigInt == bigShortClass; // true
boolean bigB3 = bigInt == bigIntClass; // true
boolean bigB4 = bigIntClass == bigShort; // true
// boolean bigB5 = bigIntClass == bigShortClass; // bug, cannot run
boolean bigB6 = bigShort == bigShortClass; // true
// WARNING: 包装类之间的比较,尽量是equals
// 整数包装类如果在[-128, 128)之间,使用常量池进行处理,也就是类似于普通变量之间的处理,
// 对于在这个外围之外的,则当做类型进行处理,而类对象进行==比较,也就是比较地址是否相同。
boolean sameb1 = smallIntClass == sameSmallIntClass; // true
boolean sameb2 = bigIntClass == sameBigIntClass; // false
boolean sameb3 = smallShortClass == sameSmallShortClass; // true
boolean sameb4 = bigShortClass == sameBigShortClass; // false
System.out.println();
}
/**
* 对于null指针存在的一些特殊情况的处理
* 为什么要考虑null,在写程序的时候,可能会出现int == null这样的比较,需要多加注意。
* 在null处理上Objects.equals是最“安全”的(这里的安全,是在损失正确率的情况下,提高防止空指针报错的情况)
*/
private static void testEqualExistNull() {
// boolean b0 = bigInt.equals(null); // bug, cannot run
boolean b1 = bigIntClass.equals(null); // false
boolean b2 = Objects.equals(bigInt, null); // false
boolean b3 = Objects.equals(bigIntClass, null); // false
// boolean b4 = bigInt == null; // bug, cannot run
boolean b5 = bigIntClass == null; // false
// boolean b6 = bigInt == ((int)null); // bug. int(null)这种强制类型转换,会报错。
// 对于这种强制类型转换,需要注意someObject不能为null, 同时someObject.getSomeValue()也不能为空。
// (int)(someObject.getSomeValue())
// small的情况,与big一致
System.out.println();
}
}
总结
- 对于大整数跟小整数进行比较的时候,需要留意==时,包装类是否在[-128, 128)的情况
- 如果已知不存在空指针的情况,==的逻辑正确率是最高的。
- 对于未知变量,还有空指针的情况,使用Objects.equals()可减少错误的发生