0

我的代码没有给出正确的结果,我开始排除故障并发现了一个奇怪的错误,有人可以向我解释一下。

如果我拿起这些字段并这样做,它会变成 result1 == false 和 result2 == true,为什么?

        MyClass m1 = new MyClass();
        MyClass m2 = new MyClass();

        Field[] fieldsFirst = m1.getClass().getDeclaredFields();
        Field[] fieldsSecond =  m2.getClass().getDeclaredFields();

        for (int i = 0; i < fieldsFirst.length; i++) {

            Field first = fieldsFirst[i];
            Field second = fieldsSecond[i];

            first.setAccessible(true);
            second.setAccessible(true);

            if(first.get(m1) instanceof Boolean)
            {
               boolean b1 = (Boolean)first.get(m1); 
               boolean b2 = (Boolean)second.get(m2);

               //Here are the results
               boolean result1 = b1 != b2; // false
               boolean result2 = (Boolean)first.get(m1) != (Boolean)second.get(m2); // true

            }

如果我有:

public class MyClass {

private boolean myBoolean = true;

public boolean getMyBoolean()
{
return myBoolean;
}
public void setMyBoolean(booelan inBool)
{
myBoolean = inBool;
}

}
4

3 回答 3

4

boolean result1 = b1 != b2; // false

您正在比较原始值,b1以及从到的拆箱转换b2的结果。Booleanboolean

boolean result2 = (Boolean)first.get(m1) != (Boolean)second.get(m2); // true

您正在比较参考。每个结果get()都是引用不同的对象。因此,!=比较是true

于 2013-10-21T14:41:16.653 回答
2

Boolean是原始的包装器boolean

包装器类包装(包围)数据类型并赋予其对象外观。只要需要数据类型作为对象,就可以使用该对象。包装类包括解包对象并返回数据类型的方法。

来源:http ://way2java.com/java-lang/wrapper-classes/

就像其他对象一样,如果您需要比较它们的值,您需要使用.equals()而不是比较运算符。

这里:

boolean b1 = (Boolean)first.get(m1); 
boolean b2 = (Boolean)second.get(m2);  

您正在转换Booleanboolean. 这被称为unboxing conversionwhich 是AutoBoxing Conversions. 之所以调用它们,是Auto因为 Java 会自动为您进行转换;即使你摆脱了演员阵容。
因此,您正在比较它们的原始值。
由于原始值相同,因此您的比较结果为真。因此,false

这里:

boolean result2 = (Boolean)first.get(m1) != (Boolean)second.get(m2);  

您正在比较两个对象的引用。由于它们存储在不同的内存位置,因此比较的结果是true. 直觉,不是吗?不同的对象,不同的内存位置?.

如果您确实需要比较两个对象的值,请使用equals()方法。但是,如果是Wrapper对象,请闭上眼睛,将它们拆箱为原始值,然后进行比较。

就像 Josh Bloch 在 Effective Java: Comparing Wrappers 中建议的那样?拆箱吸盘!!
仅来自 Effective Java 的更多内容,比较运算符在Wrapper类的情况下工作,如果它们附加了大于或小于符号。<, <=, >,>=即使您不拆箱,也会产生正确的结果。==并且!=不产生正确的结果

于 2013-10-21T14:45:15.397 回答
1

比较boolean result1 = b1 != b2是原始值比较,因此您可以使用 == 或 != 等运算符。

比较boolean result2 = (Boolean)first.get(m1) != (Boolean)second.get(m2)是对象比较,因此您不是在比较值,而是在比较引用。您应该使用 equals() 比较它们

喜欢boolean result2 = ((Boolean)first.get(m1)).equals((Boolean)second.get(m2))

于 2013-10-21T14:42:49.443 回答