Java 比较中的double和double的区别

Java 比较中的double和double的区别,java,double,Java,Double,我知道Double是一个包装类,它包装Doublenumber。今天,我看到了另一个主要区别: double a = 1.0; double b = 1.0; Double c = 1.0; Double d = 1.0; System.out.println(a == b); // true System.out.println(c == d); // false 对我来说太奇怪了 因此,如果我们使用双倍,每次我们都必须这样做: private static final double d

我知道
Double
是一个包装类,它包装
Double
number。今天,我看到了另一个主要区别:

double a = 1.0;
double b = 1.0;
Double c = 1.0;
Double d = 1.0;
System.out.println(a == b);  // true
System.out.println(c == d);  // false
对我来说太奇怪了

因此,如果我们使用双倍,每次我们都必须这样做:

private static final double delta = 0.0001;
System.out.println(Math.abs(c-d) < delta); 
private静态最终双增量=0.0001;
系统输出打印LN(数学abs(c-d)

我无法解释为什么Double直接做比较是错误的。请为我解释。

c
d
在技术上是两个不同的对象,
=
操作符只比较引用

c.equals(d)
更好的方法是比较值,而不是引用。但仍然不理想。直接比较浮点值应始终考虑一些错误(epsilon)(
Math.abs(c-d)

请注意:

Integer c = 1;
Integer d = 1;
这里的比较将产生
true
,但这更复杂(
Integer
内部缓存,如中所述):

此方法将始终缓存-128到127(含)范围内的值,并且可能缓存此范围之外的其他值

为什么
valueOf()
?由于此方法隐式用于实现自动装箱:

Integer c = Integer.valueOf(1);
Integer d = Integer.valueOf(1);
另见

使用
equals()
检查两个对象的相等性
=
检查这两个引用是否引用了内存中的同一对象。

当应用于类类型的表达式时,
=
将始终执行引用比较()。所以这一行:

System.out.println(c == d); 
正在检查
c
d
是否引用相同的对象。Java中的自动装箱总是(我相信)为
float
double
创建一个新对象(整型1的情况更复杂)。因此,
c
d
引用不同的对象,因此它打印
false

如果要比较对象是否相等,则需要显式调用
equals

System.out.println(c.equals(d));
使用
double
,它将使用数字相等-如中所述。因此,行为上存在差异



1对于整型自动装箱,“小”值被缓存-因此自动装箱5(假设)每次都将返回相同的引用。“小”的定义是特定于实现的,但保证在-128到127的范围内。有关详细信息,请参见的底部。

内容检查仅适用于检查基本类型时的
=
。对于对象类型,最好使用
equals
方法:

c.equals(d)

之间的差异等于

在基本数据类型上使用
==
与在对象引用数据类型上使用它不同

  • 在基本数据类型上,
    =
    用作
    等于
  • 对于对象引用数据类型,
    =
    引用它们的引用。因此 对象在内存中指向的内容
  • 考虑案例1

        double d1 = 10.00;
        double d2 =10.00;
        System.out.println(d1 == d2); 
    
    *输出为*
    true

    案例2:
    =
    参考数据类型

        Double d1 = 10.00;
        Double d2 =10.00;
        System.out.println(d1 == d2);
    
    *输出为*
    false

    d1和d2具有不同的内存引用

    检查此有效性请考虑以下代码

        Double d1 = 10.00;
        Double d2 = d1;
        System.out.println(d1 == d2);
    
    这将打印
    true
    ,因为d1和d2指向相同的内存引用

    因此

    Java
    使用
    =
    比较原语,并检查两个变量是否引用相同的对象

    `equals'

    用于检查两个
    对象是否等效

    它还取决于所调用对象的实现。对于
    字符串
    equals()
    检查其中的字符

        Double d1 = 10.00;
        Double d2 = 10.00;
        System.out.println(d1.equals(d2));
    
    打印
    true
    ,因为它看起来像d1和d2中的内容

    案例1将不会编译


    使用
    c.equals(d)
    代替
    =
    <代码>=
    只检查引用。@Baz啊,我明白了。双人是一门课。它将比较对象而不是比较值。这个问题就像我们处理
    字符串时遇到的一样。应该使用
    equals
    而不是
    =
    :)另一个区别是Double allow null value,但Double not.Oh。我明白了。这个问题就像我们处理字符串类时一样。但是你的第二个例子很有趣。你能告诉我为什么在处理整数时它是真的吗:)@hqt:查看我答案的“另请参阅”部分中的链接。@hqt你可以称它为整数池。Sized-使用
    equals()
    =
    这两种方法,此范围内的所有整数都是相等的,我想Jon会更好地记住这一点:),因此范围是从-128到127(而不是我前面写的-256->255)。总数为256,正好是字节范围。@hqt尝试一些准备SCJP/OCPJP证书的书。你会很快发现;)或者只是阅读关于整数缓存的有效Java(我想它也在那里),你能告诉我为什么你会知道这一点吗?我在我读过的任何java书籍中都没有看到这种东西。(我不认为你已经学会了所有的Java规范:D)@hqt即使你不知道所有的规范,过一段时间你就会知道其中的大部分。这是一个很好的实践,每当你看到你不知道它是如何工作的,你去检查规格和/或来源。新知识使您成为一名更好的开发人员,并降低了出现bug的风险。