Java 理解双重自动装箱

Java 理解双重自动装箱,java,double,autoboxing,Java,Double,Autoboxing,考虑以下示例: public static void main(String[] args) { double x1 = 0.0, y1 = -0.0; Double a1 = x1, b1 = y1; System.out.println(x1 == y1); //1, true System.out.println(a1.equals(b1)); //2, false double x2 = 0.0, y2 = 0.0; Dou

考虑以下示例:

public static void main(String[] args) {
    double x1 = 0.0, y1 = -0.0;
    Double a1 = x1, b1 = y1;
    System.out.println(x1 == y1);       //1, true
    System.out.println(a1.equals(b1));  //2, false

    double x2 = 0.0, y2 = 0.0;
    Double a2 = x2, b2 = y2;
    System.out.println(x2 == y2);       //3, true
    System.out.println(a2.equals(b2));  //4, true

    double x3 = 0.0/0.0, y3 = 0.0/0.0;
    Double a3 = x3, b3 = y3;
    System.out.println(x3 != y3);       //5, true
    System.out.println(!a3.equals(b3)); //6, false
}
我试图理解
Double
的自动装箱,但无法理解。为什么
//2
打印
false
,而
//4
打印
true
,而
//1
//3
都打印
true
。为什么它们以不同的方式自动装箱

参考以下章节,我意识到它没有具体化:

如果p是类型为double的值,则:

  • 如果p不是NaN,装箱转换将p转换为r的引用 类和类型Double,使r.doubleValue()的计算结果为p

  • 否则,装箱转换将p转换为类的引用r 并键入Double,使r.isNaN()的计算结果为true


因此,
//2
//4
//6
是否存在未指定的行为,并可能根据实现的不同而产生不同的结果?

除非指定不同,否则所有JAVA数字类型都是有符号的

因此,0.0在二进制中表示为0000000…….0000000

-0.0表示为 10000000…….0000000

现在,据我所知,当您使用equals()时,比较是从2个内存位置以逐位方式进行的,因此在您的情况下会失败

来自java.lang.Double包

Double.equals(Double)
实现如下

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

双等于方法记录在中。double==操作记录在中

对于大多数数字对,它们的结果相同,但它们基于不同的约定

double==与IEEE 754算法兼容,在该算法中,NaN不等于任何东西,甚至不等于它本身,但0.0和-0.0是相等的


Double的设计目的是使equals方法与compareTo兼容,反映总顺序,并与其哈希代码兼容,因此哈希表将使用双键。NaN被视为与自身相等,-0.0小于,而不是等于0.0。

如果仔细阅读Javadoc for
Double
,您会注意到负零和正零并不相等,至少在使用
equals()进行比较时是如此:

从:

请注意,在大多数情况下,对于类Double的两个实例d1和d2,d1.equals(d2)的值为真当且仅当

d1.doubleValue() == d2.doubleValue() 
d1.doubleValue() == d2.doubleValue() 
也有真正的价值。但是,有两个例外:

如果d1和d2都表示Double.NaN,那么equals方法返回true,即使Double.NaN==Double.NaN的值为false。 如果d1表示+0.0,而d2表示-0.0,反之亦然,则即使+0.0==-0.0的值为真,相等测试的值也为假。

…对于类Double的两个实例,d1和d2 d1.等于(d2)为真当且仅当

d1.doubleValue() == d2.doubleValue() 
d1.doubleValue() == d2.doubleValue() 
也有真正的价值。但是,有两个例外:

如果d1和d2都表示Double.NaN,那么equals方法返回true,即使Double.NaN==Double.NaN的值为false

如果d1表示+0.0,而d2表示-0.0,或者反之亦然,则即使+0.0==-0.0具有该值,相等测试的值也为false 对

此定义允许哈希表正常运行

请参阅:

Javadoc of:

请注意,在大多数情况下,对于类
Double
d1
d2
的两个实例,
d1.equals(d2)
的值为
true
当且仅当

d1.doubleValue() == d2.doubleValue() 
d1.doubleValue() == d2.doubleValue() 
还具有值
true
。但是,有两个例外:

  • 如果
    d1
    d2
    都表示
    Double.NaN
    ,则
    equals
    方法返回
    true
    ,即使
    Double.NaN==Double.NaN
    具有值
    false
  • 如果
    d1
    表示
    +0.0
    ,而
    d2
    表示
    -0.0
    ,或者反之亦然,
    equal
    测试的值为
    false
    ,即使
    +0.0==-0.0
    的值为
    true
此定义允许哈希表正常运行


有您确切问题的答案。逐位为True,但NaN值“折叠为单个”规范“NaN值”。请参阅和的javadoc。从Java源程序包中添加了
Double.equals(Double)
方法的内部实现。@Saibot浮点使用符号和大小,而不是2的补码-0.0的符号位为1,其余的位为0。请详细解释一下,
+0.0==-0.0
是如何变为真的?