简单 == 而不是 doubleToLongBits

simple == instead of doubleToLongBits

我有两个双精度值(原始类型和非对象!),当我让 Eclipse 为这些双精度值生成 equals/hashCode 时,它会覆盖它那:

@Override
public boolean equals(Object obj) {
...
return Double.doubleToLongBits(mydouble) == Double.doubleToLongBits(obj.mydouble) && ..;

}

所以它使用doubleToLongBits来比较是否相等。但是,当使用 doubleToLongBits 时,0!=-0 returns 的比较是错误的。为什么在 equals 方法中需要这个?

我的问题:为什么 Eclipse 不简单地使用

 @Override
 public boolean equals(Object obj) {
 ..
 return mydouble == obj.mydouble && ..;
 }

比较是否相等?这会是错误的吗?

问题是针对原始类型的,以及为什么人们应该 doubleToLongBits 使用原始类型而不是简单地使用,例如0.1 == 0.1.

它是这样做的,因为它遵循 Double.compare() 实现 - 所以它与 Java 默认提供的一致:

public static int compare(double d1, double d2) { //Java 12 implementation
    if (d1 < d2)
        return -1;           // Neither val is NaN, thisVal is smaller
    if (d1 > d2)
        return 1;            // Neither val is NaN, thisVal is larger

    // Cannot use doubleToRawLongBits because of possibility of NaNs.
    long thisBits    = Double.doubleToLongBits(d1);
    long anotherBits = Double.doubleToLongBits(d2);

    return (thisBits == anotherBits ?  0 : // Values are equal
            (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
             1));                          // (0.0, -0.0) or (NaN, !NaN)
}

编辑:也等于 class

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

要回答"Why does Eclipse use doubleToLongBits"?

这是代码生成功能。 Eclipse 不知道上下文。它只是试图咕哝出一些基本上没问题的东西。如果它生成类似 this.d == that.d 的东西,它将触发各种静态分析工具,这些工具会将行标记为比较两个双精度数(因为它们有像 this one 这样的规则)。相反,它比较 long 并且静态分析工具很高兴,因为它们很愚蠢(对很多事情很有用,但很容易被愚弄)。

如果您使用的是双精度数,那么在一定范围内区分两个值是没有用的。在这方面,这些替代方案中的任何一种都比另一种更能帮助您。这只是静态分析工具触发次数多于其他一次的原因。

通常,当您创建一个 equals 方法时,它是针对某个域对象的。 equals 和 hashcode 方法不一定考虑对象上的所有字段,很多时候它们使用称为业务键的子集,该子集唯一标识对象。可能在这里您根本不需要在 equals 或 hashCode 方法中包含此字段。同样,代码生成器没有上下文可以继续,并且将提供一种方法来包含所有字段,无论它是否有意义。