Java 为什么hamcrest说字节0不等于整数0?
使用标准的JUnit断言和hamcrest的断言,考虑以下测试用例:Java 为什么hamcrest说字节0不等于整数0?,java,junit,hamcrest,Java,Junit,Hamcrest,使用标准的JUnit断言和hamcrest的断言,考虑以下测试用例: byte b = 0; int i = 0; assertEquals(b, i); // success assertThat(b, equalTo(i)); // java.lang.AssertionError: Expected: <0> but: was <0> if (b == i) { fail(); // test fails, so b == i is true for t
byte b = 0;
int i = 0;
assertEquals(b, i); // success
assertThat(b, equalTo(i)); // java.lang.AssertionError: Expected: <0> but: was <0>
if (b == i) {
fail(); // test fails, so b == i is true for the JVM
}
字节b=0;
int i=0;
资产质量(b,i);//成功
断言(b,等于(i));//java.lang.AssertionError:应为:但:为
如果(b==i){
fail();//测试失败,因此对于JVM,b==i为真
}
为什么会这样?JVM的值显然相等,因为b==i
是true
,所以为什么hamcrest
失败?是一种通用方法。基元类型不适用于泛型。在这种情况下,byte
和int
分别被装箱到byte
和Integer
然后变成(在资产中,
)
的实现检查参数的类型是否为Byte
,如果不是,则立即返回false
另一方面,assertEquals
是在这种情况下,byte
和int
参数都提升为long
值。在内部,它对两个相等的原语long
值使用=
请注意,这种装箱转换之所以有效,是因为
assertThat
被声明为
public static <T> void assertThat(T actual, Matcher<? super T> matcher) {
publicstaticvoid资产(T actual,Matcher之所以发生这种情况,是因为int
和byte
被装箱为Integer
和byte
,因为hamcrest Matcher对对象而不是对原语进行操作。因此,您将Integer
与byte
进行比较,而byte.equals()的实现是:
public boolean equals(Object obj) {
if (obj instanceof Byte) {
return value == ((Byte)obj).byteValue();
}
return false;
}
和Integer.equals()
:
换句话说,Integer
和Byte
总是不相等的。在比较原语时,只需使用Assert.assertEquals
即可。hamcrest匹配器功能强大,但主要用于(复杂)对象断言。因为Byte.valueOf((Byte)0).等于(Integer.valueOf(0))
为false。如上面的assylias示例所示,字节自动装箱到字节对象中。如中所示,它使用Object1.equals(Object2)。由于字节和int都是原语,因此它会自动装箱到字节和整数对象中。Byte1.equals(Integer1)即使这些装箱对象的值相同,也将返回false。Java有没有理由不检查相同范围内的值?例如if(obj instanceof Integer){return((Integer)obj).intValue()=(int)value;}
inByte.equals()
?@sina好吧,这可能就是我们可以使用原语的原因。当Java比较两个对象时,它首先检查两个对象是否属于同一类型;如果不是,它只返回false。Integer
和Byte
是对象,因此它们也适用于原语。if(新字节(0)).equals(新整数(0))
会返回true这对我来说有点奇怪。一个类似的例子是if(new Dog(“Luke”))。equals(new Cat(“Luke”)
会返回true,只是因为它们有相同的名字(我知道,这不是最好的例子,但是你会发现如果返回true,看起来有多奇怪)@KevinCruijssen当装箱发生时,这是一件你无法预料的事情。有人可能会认为,数字
可能需要一个允许整数
和字节
可比的等式,但这可能再次导致浮点
和双精度
或非常复杂的实现出现意外行为将“其他”号码类型考虑在内。
public boolean equals(Object obj) {
if (obj instanceof Byte) {
return value == ((Byte)obj).byteValue();
}
return false;
}
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}