场景:本周在完成一个公司业务功能时,在判断是否为代叫单时调用了equal方法:

PublishOrderType.HELP_ORDER.equals(valetOrderExtraInfoDO.getHelpFlag())

HELP_ORDER为枚举变量,比较的getHelpFlag()返回值为Integer,使得所有情况都返回false,导致业务逻辑错误

  分析原因:equal为java的Object中的方法,因此除了基本类型外其他所有类型都可以调用,Object中方法定义如下:

public boolean equals(Object obj) {
    return (this == obj);
}

当不同类型进行比较时,如果不是可以隐式转换,一般返回false。比较时应当比较枚举型的code,代码如下:

PublishOrderType.HELP_ORDER.getCode().equals(valetOrderExtraInfoDO.getHelpFlag())

  equal方法:

  大家都知道,对于内置类型,使用==两边的值大小,而对于超类Object派生的类型,与==相比,equal方法比较的是内容,而==比较的内存地址,java中JDK提供的常用类都equal方法进行了重写,比如:

枚举类Enum:

public final boolean equals(Object other) {
    return this==other;
}

整型类Integer:

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

双精度浮点类Double:

 public boolean equals(Object obj) {
     return (obj instanceof Double) && (doubleToLongBits(((Double)obj).value) == doubleToLongBits(value));
}

字符串类String:

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
}

注意:上面判断是不是同一个类是使用的是instanceof,这个词的含义是判断其左边对象是否为其右边类的实例或者子类的实例,而上面的几个类在定义时使用了final,也就是说不允许继承,因此可以使用该关键字,在自己编写equal方法时,需要使用.getClass() == this.getClass()判断类型是否一致;

  equal方法有以下五个性质:

  1. 自反性
  2. 对称性:不管谁调equal方法都不会影响结果
  3. 传递性
  4. 一致性:多次比较不会影响判断结果
  5. 任何非空对象与调用equal(null)均返回false

  java中需要选用合适的方法比较

  1. 对象域,使用equals方法 。
  2. 类型安全的枚举,使用equals或== 。
  3. 可能为null的对象域 : 使用 == 和 equals 。
  4. 数组域 : 使用 Arrays.equals 。
  5. 除float和double外的原始数据类型 : 使用 == 。
  6. float类型: 使用Float.floatToIntBits转换成int类型,然后使用==。
  7. double类型: 使用Double.doubleToLongBit转换成long类型,然后使用==。

  总的来说:类一般调用equal判断,当然首先需要对类进行判空,除了float和double之外的内置类型直接使用==进行内容比较,而float和double使用Float和Double的方法比较,也可以先生成Float或者Double对象调用equal方法,从前面Double的equal方法中可以看出,实质上还是调用了[float/double]To[Int/Long]Bit方法,建议直接使用该方法,避免不必要的开销。

 参考:http://www.cnblogs.com/chenssy/p/3416195.html

 posted on 2016-07-09 12:36  天际线_skyline  阅读(15593)  评论(0编辑  收藏  举报