2017-01-05 6 views
-2

私はJava 8とSpringを使用しています。最近私は奇妙な(私のために)問題があった。基本的に、私は2つのクラスがあります。は、基本クラスと拡張クラスの間で等しいです。正しく動作しません。

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. A @Configurationクラス、基底クラス拡張:

@Configuration 
@ConfigurationProperties(prefix = "config") 
@RefreshScope //org.springframework.cloud.context.config 
public MyClass extends BaseClass { 
    private int variableB; 

    /* getter and setter method */ 
} 

私が欲しいのは、かどうかを確認することですがこれは、基底クラスである 1 2つのクラスは等しく、baseClassの変数のみを考慮します。クラスabが正しく満たされているareTheyEqual方法では例の方法

public boolean areTheyEqual(BaseClass a, MyClass b) { 
    return a.equals(b); 
} 

BaseClass.equalsを見て、(HERE)と書いたとき:BaseClassMyClassから作成しました。 NullPointerではありませんが、variableAは0です(MyClassでは値に設定されています)。どうしてか分かりません!

しかし

私は方法areTheyEqualを変更する場合:

public boolean areTheyEqual(BaseClass a, MyClass b) { 
    return a.equals(new BaseClass(b)); 
} 

すべてが正常に動作します。なぜ私は本当に不思議です。それは、いくつかの問題は、使用してequals私は@ConfigurationクラスMyClassをObjectに、次にBaseClassにキャストしようとしていますか?

EDIT 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); 
    } 
} 

は(ところでメソッドはのIntelliJによって生成される)equals実装が何であるかは重要ではありません。

「正常に動作します」の私の定義は次のとおりです。その後、 1.基底クラスでvariableAは、MyClassの中variableAと同じである場合はtrueを返しますequals 2.そうでない場合は1、その後偽

+1

あなたは私たちに等価コードplsを表示できます –

+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; 
} 

彼らは正確に同じクラスであるとき、2つのオブジェクトが唯一、等しくすることができることを意味し、そのMyClassのインスタンスは、直接インスタンスに等しいことができませんBaseClassのインスタンスであり、MyClassのインスタンスではありません。

あなたが均等にすべてのBaseClassのインスタンスとそのサブクラスを扱いたい場合は、関係なく、彼らの実際の型の、あなたはinstanceofオペレータが指定した型のサブクラスのインスタンスを受け入れ

if (o == null || ! (o instanceof BaseClass)) { 
    return false; 
} 

にそのステートメントを変更する必要があります。 this instanceof BaseClassが常にtrueであることを意味するので、thisのタイプを確認する必要はありません。 o.getClass()の呼び出しとは異なり、instanceofも正しくnullを処理し、

if (! (o instanceof BaseClass)) { 
    return false; 
} 

に声明を低減することも可能である。しかし、それは簡単な形式を使用するかどうかのコーディングスタイルの決定だか、明示的なことを

注意null試験。ところで

、あなたの意図は、すべてのBaseClassインスタンスが平等の同じ定義を持っているに関係なく、実際の(サブ)タイプの、あなたは明確にするためequals方法finalを作るべきであるということです。

関連する問題