Johan Nordli
Johan Nordli

Reputation: 1230

Different results with Boolean and boolean in java

My code did not give the correct result and I begin to troubleshoot and discovered a strange error, can someone explain this to me.

If I pick up the fields and doing this it becomes result1 == false and result2 == true, why?

        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

            }

If I have:

public class MyClass {

private boolean myBoolean = true;

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

}

Upvotes: 0

Views: 120

Answers (3)

An SO User
An SO User

Reputation: 24998

Boolean is a wrapper around the primitive boolean.

a wrapper class wraps (encloses) around a data type and gives it an object appearance. Wherever, the data type is required as an object, this object can be used. Wrapper classes include methods to unwrap the object and give back the data type.

Source: http://way2java.com/java-lang/wrapper-classes/

Just like with other objects, if you need to compare their values, you need to use .equals() and not the comparison operators.

Here:

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

You are converting the Boolean to boolean. This is called as unboxing conversion which is a part of the AutoBoxing Conversions. These are called Auto because Java automatically does that conversion for you; even if you get rid of the cast.
Hence, you are comparing their primitive values.
Since the primitive values are the same, your comparison evaluates to true. Hence, false

Here:

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

You are comparing the references of the two objects. Since they are stored in different memory locations, the result of the comparison is true. Intuitive, isn't it? Different object, different memory location?.

If you really need to compare the values of two objects, use the equals() methods. In case of Wrapper objects however, close your eyes, unbox them to their primitive values and then compare.

Just like Josh Bloch suggests in Effective Java: Comparing Wrappers? Unbox the suckers!!
Just more from Effective Java, comparison operators work in case of Wrapper class if they have a greater than or less than sign attached to them. <, <=, >, >= yield the correct result even if you do not unbox. == and != do not yield correct result

Upvotes: 2

Cristian Meneses
Cristian Meneses

Reputation: 4041

The comparation boolean result1 = b1 != b2 is a primitive value comparation, so you can use operators like == or !=.

The comparation boolean result2 = (Boolean)first.get(m1) != (Boolean)second.get(m2) is an object comparation, so you are not comparing values, but references. You should compare them by using equals()

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

Upvotes: 1

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279970

In

boolean result1 = b1 != b2; // false

you are comparing primitive values, as b1 and b2 result from unboxing conversion from Boolean to boolean.

In

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

you are comparing references. The result of each get() is referencing a different object. As such, the != comparison is true.

Upvotes: 4

Related Questions