我知道Double是一个包装类,它包装了Double号。今天,我看到了另一个主要区别:
1 2 3 4 5 6
| 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 |
我真奇怪!!!!
所以,如果我们每次使用Double,我们必须这样做:
1 2
| private static final double delta = 0.0001;
System. out. println(Math. abs(c -d ) < delta ); |
我不能解释为什么双重比较是错误的。请给我解释一下。
谢谢)
- 用c.equals(d)代替==。==只检查引用。
- @啊,我明白了。双人房是一门课。它将比较对象而不是比较值。这个问题就像我们处理String一样。应使用equals而不是==。
- 是的,正是…
c和d在技术上是两个不同的对象,==操作符只比较引用。
比较值而不是引用时更好。但仍然不理想。直接比较浮点值应始终考虑一些错误(epsilon)(Math.abs(c - d) < epsilon)。
注意:
这里的比较将产生true,但这更复杂(Integer内部缓存,在Integer.valueOf()的javadoc中描述):
This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
为什么是valueOf()?因为此方法隐式地用于实现自动氧化:
也见
- 哦.我明白了。这个问题喜欢我们处理字符串类的时候。但是你的第二个例子很有趣。你能告诉我为什么整数是真的吗:)
- @HQT:查看我答案的另一部分中的链接。
- @你可以称之为整数池。大小<-128127>-此范围内的所有整数都使用equals()和==相等。
- 哦.很好的链接:)我不知道为什么这里的很多人都知道这种知识。我以前在Java书中看不到这一点。(关于整数pol:)
- 我想乔恩更清楚地记得这一点:),所以范围是从-128到127(不像我之前写的那样-256->255)。总数为256,正好是字节范围。
- @HQT尝试一些书准备SCJP/OCPJP证书。你会发现它相当快;)或者只是阅读有效的Java(我想它也在那里)
- 谢谢。我会尝试:
- 比较浮点数时要非常小心。主题是一个雷区。参见cygnus software.com/papers/comparingfloats/comparingfloats.h&zwnj;&8203;tm和其中的float-point-gui.de/references和references。
当应用于类类型的表达式时,==将始终执行引用比较(jls第15.21.3节)。所以这条线:
正在检查c和d是否引用相同的对象。Java中的自动装箱(我相信)为EDCOX1、13和EDCOX1 14创建了一个新的对象(对于整数类型来说情况更复杂)。因此,c和d是指不同的对象,所以它打印false。
如果要比较对象是否相等,需要显式调用equals:
1
| System. out. println(c. equals(d )); |
对于double,它使用的是数字相等,如第15.21.1节所述。因此行为上的差异。
1对于整体自动氧化,"小"值被缓存-因此自动氧化5(say)将每次返回相同的引用。"小"的定义是特定于实现的,但它保证在-128到127的范围内。详情见第5.1.7节底部。
- +1个很好的细节!
- 关于整数缓存,你能告诉我为什么你能知道这个吗?在我读过的任何一本Java书籍中,我都看不到这些东西。(我不认为你学习所有的Java规格:D)
- @即使你不完全了解所有的规范,一段时间后你也会了解其中的大部分。这是一个很好的实践,当你看到一些你不知道如何工作的东西,你就去检查规格和/或来源。新知识使您成为更好的开发人员,并降低了错误的风险。
使用equals()检查两个对象的相等性。==检查2个引用是否引用内存中的同一对象。
内容检查仅对检查基元类型时的==可靠。对于对象类型,最好使用equals方法: