java中使用布尔值和布尔值的结果不同

时间:2013-10-21 14:37:04

标签: java boolean

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

如果我拿起字段并执行此操作,它将变为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;
}

}

3 个答案:

答案 0 :(得分:4)

boolean result1 = b1 != b2; // false

您正在比较原始值,b1b2来自Boolean的{​​{1}}到boolean

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

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

答案 1 :(得分:2)

Boolean是原始boolean的包装器。

  

包装器类围绕数据类型包装(封闭)并给它一个   物体外观。无论何处,数据类型都需要作为对象,   可以使用此对象。包装类包括解包方法   对象并返回数据类型。

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

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

这里:

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

您正在将Boolean转换为boolean。这被称为unboxing conversion,它是AutoBoxing Conversions的一部分。这些被称为Auto,因为Java会自动为您进行转换;即使你摆脱演员。
因此,您正在比较它们的原始值 由于原始值相同,因此您的比较评估为true。因此,false

这里:

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

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

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

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

答案 2 :(得分: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))