我的代码没有给出正确的结果,我开始排除故障并发现一个奇怪的错误,有人可以向我解释一下。
如果我拿起字段并执行此操作,它将变为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;
}
}
答案 0 :(得分:4)
在
boolean result1 = b1 != b2; // false
您正在比较原始值,b1
和b2
来自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))