2017-01-05 4 views
-2

Ich verwende Java 8 und Spring. Vor kurzem hatte ich ein seltsames (für mich) Problem. Grundsätzlich habe ich zwei Klassen: 1. Es ist eine Basisklasse:gleich zwischen Basis und erweiterte Klasse funktioniert nicht richtig

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. Eine @Configuration-Klasse, die die Basisklasse erweitert:

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

    /* getter and setter method */ 
} 

Alles, was ich will, ist zu prüfen, ob Zwei Klassen sind gleich, wobei nur Variablen in baseClass berücksichtigt werden. Beispielverfahren

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

Bei dem Verfahren areTheyEqual die Klassen ab und korrekt gefüllt sind. Wenn Sie BaseClass.equals zu Zeile schauen, wo (HERE) geschrieben wird: In diesem Punkt habe ich einige BaseClass erstellt von MyClass. Es ist kein NullPointer, aber variableA ist gleich 0 (in MyClass wurde auf einen Wert gesetzt). Ich weiß nicht warum!

aber

wenn ich ändern die Methode areTheyEqual zu:

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

alles funktioniert. Ich bin wirklich neugierig, warum ist das so? Ist es ein Problem, dass ich unter Verwendung equals @Configuration-Klasse MyClass auf Objekt und dann auf BaseClass umwandeln?

EDIT 1: Beispiel:

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

In meiner Frage ist nicht wichtig, was equals Implementierung ist (btw Methode von IntelliJ erzeugt wird).

Meine Definition von 'funktioniert' ist: 1. Wenn variableA in Baseclass ist die gleiche wie variableA in myClass dann equals true zurück 2. Wenn nicht 1. dann falsch

+1

können Sie uns den Equals-Code zeigen pls –

+1

Wir können dies nicht beantworten, weil es zu viel Code fehlt, und wir wissen nicht, was Ihre Definition von "funktioniert gut" ist. Was meinst du mit "in' MyClass' wurde es auf einen Wert gesetzt "? Wo war es und wie? Deine Frage ist völlig unklar. – ajb

+0

Zeigen Sie Ihre equals-Methode in 'BaseClass' an. – additionster

Antwort

0

Mit wenig Informationen gegeben, die wahrscheinlichste Ursache scheint, dass Sie die gleiche private Variable variableA in der Unterklasse neu definiert werden, wie:

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

Wenn Sie dies tun, die Basisklasse Variable 0 in der Unterklasse Instanz bleiben wird, aber Sie‘ Ich sehe immer noch, dass die Variable variableA richtig eingestellt ist, solange Sie die Unterklasse betrachten. Wenn Sie es in die Superklasse umwandeln, wird die Variable der Basisklasse sichtbar und zeigt 0.

+0

in BaseClass ist VariableA und in MyClass ist VariableB. Hier gibt es keine Neudefinition. –

2

Zuerst sollten Sie aufhören, das Wort "Klasse" zu verwenden, wenn Sie eigentlich "Objekt" oder "Instanz" meinen. Ihr Missbrauch des Begriffs macht die ganze Frage sehr schwer zu lesen.

Dann bekommen Sie, wonach Sie fragen.In Ihrer equals Implementierung gibt es die Aussage:

if (o == null || getClass() != o.getClass()) { 
    return false; 
} 

die, dass zwei Objekte impliziert nur gleich sein können, wenn sie von genau der gleichen Klasse sind, so dass eine Instanz von MyClass kann nicht auf eine direkte Instanz gleich von BaseClass das ist keine Instanz von MyClass.

Wenn Sie gleich alle Instanzen BaseClass und ihre Unterklassen zu behandeln, unabhängig von ihrem tatsächlichen Typ, müssen Sie diese Aussage ändern

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

Der instanceof Operator Instanzen von Subklassen des angegebenen Typs akzeptiert. Sie müssen den Typ this dann nicht überprüfen, da dies bedeutet, dass this instanceof BaseClass immer true ist.

Beachten Sie, dass im Gegensatz zu einem Aufruf von o.getClass(), instanceof nimmt auch null richtig, so ist es auch möglich, die Aussage zu

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

Aber es ist eine Codierungsstil Entscheidung zu reduzieren, ob die einfachere Form oder die explizite verwenden null testen.

By the way, wenn Ihre Absicht ist es, dass alle BaseClass Fälle die gleiche Definition der Gleichheit haben, unabhängig von ihrer tatsächlichen (Unter-) Art, sollten Sie die equals Methode final, für Klarheit machen.

Verwandte Themen