Puzzle 87: Strained Relations

Java中的“相等”

集合论上讲,一个相等关系,是满足下面三个条件的:

(假设“相等”用符号"~"表示)

  1. 自反性(Reflexive):对一切 x,x ~ x。亦,自身和自身相等。
  2. 传递性(Transitive):如果 x ~ y, y ~ z,则 x ~ z。
  3. 对称性(Symmetric):如果 x ~ y,则 y ~ z。

但是,囿于实际表达的限制,在Java中,==并没有在所有情况下都满足上面的三条性质。具体,在本Puzzle中有例子说明。

  1. 违反自反性的,有Double.NaN和Float.NaN。(参Puzzle 29
  2. 违反传递性,整型在向浮点转型的操作中丢失精度可能导致这个问题。
  3. 违反对称性的例子暂时没有。

关于2,书中举例的代码片段如下:

long x = Long.MAX_VALUE;

double y = (double) Long.MAX_VALUE;

long z = Long.MAX_VALUE - 1;

System.out.print((x == y) + " "); //Imprecise

System.out.print((y == z) + " "); //Imprecise

System.out.println((x == z)); // Precise

TODO:以下将记录研究附5后的一些内容。

  1. Puzzle 5, 8, 24 and 31: beware of mixed-type operations.
  2. Puzzle 29: Bride of Looper,”相等“关系不满足自反性
  3. Puzzle 34: Down for the Court,精度默默地改变容易让程序员迷惑不解。
  4. Puzzle 35: Minute by Minute
  5. JLS 5.1.2 Widening Primitive Conversion
  6. JLS 5.6.2 Binary Numeric Promotion
  7. TODO: 关于整型转浮点型,精度问题的一些讨论和现在可以参考这里