Java 为什么hamcrest说字节0不等于整数0?

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

使用标准的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 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;}
in
Byte.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;
}