Findbugs Warnung: Equals Methode sollte nichts über die Art ihres Arguments übernehmen

StackOverflow https://stackoverflow.com/questions/364454

  •  21-08-2019
  •  | 
  •  

Frage

Wenn FindBugs auf meinem Projekt laufen, ich habe ein paar Instanzen des oben beschriebenen Fehlers.

Das heißt, meine zwingenden Versionen von Gleichen warfen das RHS-Objekt in die gleiche Art wie das Objekt, in dem die übergeordnete Version definiert ist.

Allerdings bin ich nicht sicher, ob ein besseres Design möglich ist, da AFAIK Java keine Varianz in Methodenparametern erlauben, so ist es nicht möglich, eine andere Art zu definieren, für die Parameter entspricht.

Mache ich etwas sehr falsch, oder ist FindBugs zu eifrig?

Eine andere Möglichkeit, diese Frage Begriff ist: Was das richtige Verhalten ist, wenn das Objekt übergeben entspricht nicht der gleiche Typ wie ein LHS: Ist dies ein falscher, oder sollte eine Ausnahme da sein

?

Zum Beispiel:

public boolean equals(Object rhs)
{
    MyType rhsMyType = (MyType)rhs; // Should throw exception
    if(this.field1().equals(rhsMyType.field1())... // Or whatever
}
War es hilfreich?

Lösung

Normalerweise, wenn gleich die Umsetzung können Sie überprüfen, um zu sehen, ob die Klasse des Arguments gleich ist (oder kompatibel) an die implementierende Klasse, bevor sie gegossen wird. So etwas wie folgt aus:

if (getClass() != obj.getClass())
    return false;
MyObj myObj = (MyObj) obj;

es auf diese Weise Dadurch wird die FindBugs Warnung verhindern.

Eine Randnotiz einen Kommentar zu adressieren:
Einige Leute argumentieren instanceof statt getClass verwenden Typsicherheit zu überprüfen. Es gibt eine große Debatte über das, was ich versuche, nicht in zu bekommen, wenn ich festgestellt, dass Sie für die Klasse Gleichheit überprüfen oder Kompatibilität, aber ich denke, ich kann es nicht entweichen kann. Es läuft darauf hinaus, diese nach unten - wenn Sie verwenden instanceof Sie Gleichheit zwischen Instanzen einer Klasse und Instanzen ihrer Unterklasse unterstützen kann, riskieren aber den symmetrischen Vertrag equals zu brechen. Im Allgemeinen würde ich empfehlen, nicht instanceof zu verwenden, wenn Sie wissen, dass Sie es brauchen, und Sie wissen, was Sie tun. Weitere Informationen finden Sie unter:

Andere Tipps

Du bist wahrscheinlich etwas zu tun, wie folgt aus:

public class Foo {
  // some code

  public void equals(Object o) {
    Foo other = (Foo) o;
    // the real equals code
  }
}

In diesem Beispiel etwas über das Argument von Gleichen davon aus (): Sie vorausgesetzt, es ist vom Typ Foo ist. Dies muss nicht der Fall sein! Sie können erhalten auch einen String (in diesem Fall sollten Sie fast definitiv falsch zurück).

So Ihr Code soll wie folgt aussehen:

public void equals(Object o) {
  if (!(o instanceof Foo)) {
    return false;
  }
  Foo other = (Foo) o;
  // the real equals code
}

(oder den strengeren getClass() != o.getClass() von Dave L erwähnt verwendet werden.

Sie auch es auf diese Weise aussehen:

Integer i = new Integer(42);
String s = "fourtytwo";
boolean b = i.equals(s);

Gibt es einen Grund, dass dieser Code eine ClassCastException statt Finishing normal und Einstellung b werfen sollte false?

wäre sinnvoll, nicht ein ClassCastException als Antwort auf .equals() Werfen. Denn selbst wenn es sich um eine dumme Frage ( „Natürlich ist ein String ist nie gleich ein Foo!“) Es ist immer noch ein gültiger mit einer völlig in Ordnung Antwort ( „nein“ == false).

Ich würde empfehlen, Warnung, sagte findbugs zu ignorieren. In der Praxis wird, wenn gleich mit einem Objekt einer unerwarteten Klasse genannt wird, ist es fast sicher ein Fehler, und Sie wollen auf Fehler schnell zum Scheitern verurteilt.

Zum Beispiel, wenn Sie eine ‚Arraylist-Dateien‘ haben und nennen files.contains ( „MyFile.txt“), wäre es schön, wenn Sie einen Classcast bekommen. Stattdessen Java gibt nur falsch, und es dauert wahrscheinlich eine lange Zeit, bis Sie diesen Fehler entdecken.

ich meine equals (Object) Implementierungen wie folgt beginnen:

if ((object == null) || !(object instaceof ThisClass)) {
    return false;
}

Dies wird auch die FindBugs Warnung verhindern, aber nicht automatisch false zurück, wenn eine Unterklasse von ThisClass in geben wird. Es könnte auch gleich betrachtet werden, vor allem, wenn seine equals(Object) Methode überschrieben worden ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top