2017-01-05 40 views
-2

我正在使用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); 
} 

areTheyEqualab被正确填充的方法。当你看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实现(顺便说一句,通过的IntelliJ生成的方法)。

我的“工作正常”的定义是: 1.当variableA在基类是MyClass中一样variableA然后equals返回true 2.如果不是1则假

+1

您能向我们展示等于代码吗 –

+1

我们不能回答这个问题,因为缺少太多的代码,我们不知道您的“正常工作”定义是什么。 “MyClass”中的“它被设置为某个值”是什么意思?它在哪里设置,以及如何?你的问题完全不清楚。 – ajb

+0

在'BaseClass'里面显示你的equals方法 – additionster

回答

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

+0

是variableA,MyClass中是variableB。这里没有重新定义。 –

2

首先,当您实际上指“对象”或“实例”时,应停止使用“类”一词。你滥用这个词使得整个问题很难阅读。

然后,你得到你所要求的。在你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,为了清楚。

相关问题