我正在使用Java 8和Spring。最近我有一个奇怪的(对我来说)问题。基本上,我有两个类: 1.这是一个基类:
public BaseClass {
private int variableA;
public BaseClass() {
/* this is an empty costructor */
}
public BaseClass(int a) {
this.variableA = a;
}
/* getter and setter method */
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
BaseClass that = (BaseClass) o;
/* (HERE) */
return variableA == that.variableA;
}
}
2。一个@Configuration类,它扩展了基类:
@Configuration
@ConfigurationProperties(prefix = "config")
@RefreshScope //org.springframework.cloud.context.config
public MyClass extends BaseClass {
private int variableB;
/* getter and setter method */
}
我想要的只是检查两个类是否相等,只考虑baseClass中的变量。示例方法
public boolean areTheyEqual(BaseClass a, MyClass b) {
return a.equals(b);
}
在方法areTheyEqual
中,正确填写了a
和b
类。当您查看BaseClass.equals
到写(HERE)
的位置时:此时我从BaseClass
创建了一些MyClass
。它不是NullPointer,但是variableA
等于0(在MyClass中它被设置为某个值)。我不知道为什么!
但
如果我将方法areTheyEqual
更改为:
public boolean areTheyEqual(BaseClass a, MyClass b) {
return a.equals(new BaseClass(b));
}
一切正常。我真的很好奇为什么会这样。是否存在一些问题,使用equals
我将@Configuration类MyClass转换为Object然后转换为BaseClass?
编辑1: 例如:
@Component
public class Example {
private MyClass myClass;
private BaseClass baseClass;
@Autowired
public Example(MyClass myClass) {
this.myClass = myClass;
this.baseClass = new BaseClass(myClass);
}
@Scheduled
private void checkMe() {
if(!areTheyEqual()) {
/* do something */
}
}
private boolean areTheyEqual() {
/* baseClass.variableA == 2 AND myClass.variableA == 2 */
return baseClass.equals(myClass);
}
}
在我的问题中,equals
实现是什么并不重要(btw方法是由Intellij生成的)。
我对'工作正常'的定义是:
1.当baseClass中的variableA
与myClass中的variableA
相同时,equals
返回true
2.如果不是1.那么假
答案 0 :(得分:2)
首先,当你实际上是指“对象”或“实例”时,你应该停止使用“class”这个词。您滥用该术语会使整个问题难以阅读。
然后,你得到你所要求的。在equals
实现中,有声明:
if (o == null || getClass() != o.getClass()) {
return false;
}
这意味着两个对象只能是相同的,当它们属于完全相同的类时,MyClass
的实例不能等于BaseClass
的直接实例,而不是MyClass
的实例。
如果要同等地处理BaseClass
及其子类的所有实例,无论其实际类型如何,都必须将该语句更改为
if (o == null || ! (o instanceof BaseClass)) {
return false;
}
instanceof
运算符接受指定类型的子类的实例。您无需检查this
的类型,因为它暗示this instanceof BaseClass
始终为true
。
请注意,与调用o.getClass()
不同,instanceof
也正确处理null
,因此也可以将语句缩减为
if (! (o instanceof BaseClass)) {
return false;
}
但这是一种编码风格决定,是使用更简单的形式还是明确的null
测试。
顺便说一句,如果您的意图是所有BaseClass
实例都具有相同的相等定义,无论其实际(子)类型如何,您都应该使用equals
方法final
,为了清楚起见。
答案 1 :(得分:0)
由于给出的信息很少,最可能的原因似乎是您在子类中重新定义了相同的私有变量variableA
,如:
public class BaseClass {
private int variableA;
public BaseClass (int a) {
this.variableA = a;
}
}
public class MyClass extends BaseClass {
private int variableA;
public MyClass (int a) {
this.variableA = a;
}
}
如果你这样做,基类'变量在子类实例中将保持为0,但只要您查看子类,您仍然会看到它正确设置了名为variableA
的变量。如果你把它强制转换为超类,基类'变量将变为可见,显示0
。