Effective Java – Part 2

Second part of the summary based on Effective Java.

Chapter 3. Methods Common to All Objects

Item 7: Obey the general contract when overriding equals

Do not override equals if any of the following is true:

  1. Each instance of the class is inherently unique
  2. You don’t care whether the class provides a “logical equality” test
  3. A superclass has already overridden equals, and the behavior inherited from the superclass is appropriate for this class
  4. The class is private or package-private, and you are certain that its equals method will never be invoked.

Typseafe Enums do not require equals method to be overridden.
equals method implements an equivalence relation.
There is simply no way to extend an instantiable class and add an aspect while preserving the equals contract.
A workaround is to use composition (item 14).

Recipe for a high quality equals method:

  1. Use the == operator to check if the argument is a reference to this object
  2. Use the instanceof operator to check if the argument is of the correct type.
  3. Cast the argument to the correct type.
  4. For each “significant” field in the class, check to see if that field of the argument matches the corresponding field of this object.
  5. Ask yourself three questions: Is it symmetric, is it transitive, and is it consistent?
  6. Don’t try to be too clever.
  7. Don’t write an equals method that relies on unreliable resources.

Don’t substitute another type for Object in the equals declaration.

Item 8: Always override hashCode when you override equals
Equal objects must have equal hash codes.
Do not be tempted to exclude significant parts of an object from the hash code computation to improve performance.

Item 9: Always override toString
Providing a good toString implementation makes your class much more pleasant to use.
When practical, the toString method should return all of the interesting information contained in the object,
Whether or not you decide to specify the format, you should clearly document your intentions.
It is always a good idea to provide programmatic access to all of the information contained in the value returned by toString.

Item 10: Override clone judiciously
All classes that implement Cloneable should override clone with a public method.This public method should first call super.clone and then fix any fields that need fixing.
The Cloneable interface was intended as a mixin interface (Item 16) for objects to advertise that they permit cloning.
If a class implements Cloneable, Object’s clone method returns a field-by-field copy of the object; otherwise it throws CloneNotSupportedException.
In practice, a class that implements Cloneable is expected to provide a properly functioning public clone method.
In effect, the clone method functions as another constructor; you must ensure that it does no harm to the original object and that it properly establishes invariants on the clone.
The clone architecture is incompatible with normal use of final fields referring to mutable objects
Like a constructor, a clone method should not invoke any nonfinal methods on the clone under construction (Item 15).

A fine approach to object copying is to provide a copy constructor.A minor variant is to provide a static factory in place of a constructor.

Item 11: Consider implementing Comparable
compareTo method is declared in java.lang.Comparable interface.
By implementing Comparable, a class indicates that its instances have a natural ordering.
Float class’s compareTo method is inconsistent with equals

Leave a Comment