Wiki Markup |
---|
Composition or inheritence may be used to create a new class that both encapsulates an existing class and adds one or more fields. When a subclass extends another this way, the concept of equality for the subclass may or may not involve its new fields. That is, when comparing two subclass objects for equality, sometimes their respective fields must also be equal, and other times they need not be equal. WhenDepending objectson ofthe aconcept subclassof areequality compared for equality using {{Object.equals()}}the subclass, the subclass mustmight override {{equals()}}.. Furthermore, this method must follow the general contract for {{equals()}} as specified by the Java Language Specification \[[JLS 2005|AA. Bibliography#JLS 05]\]. |
...
The equals()
method applies only to objects, not primitives.
Enumerated It is unnecessary to override the equals
method when checking for logical equality. For example, enumerated types have a fixed set of distinct values that may be compared using ==
rather than the equals()
method. Note that enumerated types provide an equals()
implementation that uses ==
internally; this default cannot be overridden. More generally, subclasses that both inherit an implementation of equals()
from a superclass and also lack a requirement for additional functionality need not override the equals()
method.
...
Never violate any of these requirements when overriding the equals()
method.
Noncompliant Code Example (
...
Symmetry)
This noncompliant code
Mistakes resulting from a violation of the first requirement are infrequent; consequently we omit noncompliant code examples for this case.
Noncompliant Code Example (Symmetry)
This noncompliant code example defines a CaseInsensitiveString
class that includes a String
and overrides the equals()
method. The CaseInsensitiveString
class knows about ordinary strings but the String
class has no knowledge of case-insensitive strings. Consequently, CaseInsensitiveString.equals()
method should not attempt to interoperate with objects of the String
class.
...
Code Block | ||
---|---|---|
| ||
class XCard { private String type; private Card card; // Composition public XCard(int number, String type) { card = new Card(number); this.type = type; } public Card viewCard() { return card; } public boolean equals(Object o) { if (!(o instanceof XCard)) { return false; } XCard cp = (XCard)o; return cp.card.equals(card) && cp.type.equals(type); } public static void main(String[] args) { XCard p1 = new XCard(1, "type1"); Card p2 = new Card(1); XCard p3 = new XCard(1, "type2"); XCard p4 = new XCard(1, "type1"); System.out.println(p1.equals(p2)); // Prints false System.out.println(p2.equals(p3)); // Prints false System.out.println(p1.equals(p3)); // Prints false System.out.println(p1.equals(p4)); // Prints true } } |
Noncompliant Code Example (Consistency)
The consistency requirement implies that mutable objects may be unable to satisfy the equals()
contract. Consequently, it is good practice to avoid defining equals()
implementations that use unreliable data sources such as IP addresses and caches.
Noncompliant Code Example (Non-null references)
...
Exceptions
Wiki Markup |
---|
*MET12-EX0:* This guideline may be violated provided that the incompatible types are never compared. There are classes in the Java platform libraries (and elsewhere) that extend an instantiable class by adding a value component. For example, {{java.sql.Timestamp}} extends {{java.util.Date}} and adds a nanoseconds field. The {{equals}} implementation for {{Timestamp}} violates symmetry and can cause erratic behavior if {{Timestamp}} and {{Date}} objects are used in the same collection or are otherwise intermixed. \[[Bloch 2008|AA. Bibliography#Bloch 08]\] |
...