Reputation: 1230
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
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
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
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