Effective Java 3rd Edition Chapter 3 Methods Common to All Objects

[Effective Java 3rd Edition](https://www.amazon.co.jp/Effective-Java-%E7%AC%AC3%E7%89%88-%E3%], which is a must-have book for intermediate Java users and above. 82% B8% E3% 83% A7% E3% 82% B7% E3% 83% A5% E3% 82% A2% E3% 83% BB% E3% 83% 96% E3% 83% AD% E3% 83% 83% E3% 82% AF-ebook / dp / B07RHX1K53) has a Kindle version, so I will summarize it.

Previous: Effective Java 3rd Edition Chapter 2 Object Creation and Disappearance Next: Effective Java 3rd Edition Chapter 4 Classes and Interfaces

Item 10 When overriding equals, follow the general contract

--If you override equals the wrong way, the consequences can be disastrous. --The easiest way to avoid problems is not to override.

The correct way to do this is not to override if any of the following conditions are true:

--Each instance of a class is inherently unique. --The class does not have to provide a "logical equivalence" check. --The superclass has already overridden equals and the behavior of the superclass is appropriate for this class, --It is certain that the class is private or package private and its equals method is not called.

The equals method implements an equivalence relation and has the following properties:

--Reflective: For null, x.equals (x) must return true for any reference value x. --Contrast: x.equals (y) must return true only if y.equals (x) returns true for any non-null reference values x and y. .. --Transitive: For any non-null reference values x, y, z, if x.equals (y) and y.equals (z) return true, then x.equals ( z) must return true. --Consistent: For any non-null reference value x, y, multiple calls to x.equals (y) will consistently set true if the information used in the equals comparison has not changed. Must either return or consistently return false. --For any non-null reference value x, x.equals (null) must return false.

[Good]Equal override example



public final class PhoneNumber {
    private final short areaCode, prefix, lineNum;

    public PhoneNumber(int areaCode, int prefix, int lineNum) {
        this.areaCode = rangeCheck(areaCode, 999, "area code");
        this.prefix = rangeCheck(prefix, 999, "prefix");
        this.lineNum = rangeCheck(lineNum, 9999, "line num");
    }

    private static short rangeCheck(int val, int max, String arg) {
        if (val < 0 || val > max) {
            throw new IllegalArgumentException(arg + ": " + val);
        }
        return (short) val;
    }

    //[Good example] Override example of equal
    @Override
    public boolean equals(Object o) {
        if (o == this) {
            //Is it a reference to your own object?
            return true;
        }
        if (!(o instanceof PhoneNumber)) {
            //Is it the correct type?
            return false;
        }
        //Cast with the correct type
        PhoneNumber pn = (PhoneNumber) o;
        //Does it match for each of the meaningful folds?
        return pn.lineNum == lineNum && pn.prefix == prefix && pn.areaCode == areaCode;
    }
}

Equals method automatically generated by IntelliJ


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PhoneNumber that = (PhoneNumber) o;
        return areaCode == that.areaCode &&
                prefix == that.prefix &&
                lineNum == that.lineNum;
    }

--By using Google's AutoValue framework, equals and hashCode are automatically generated by annotation.

Item 11 Always override hashCode when overriding equals

hash method contract

--If the hashCode method is repeatedly called on the same object while the application is running, the hashCode method must always return the same value unless there is a change in the object's information used in the equal comparison. This value does not have to match for one run of the same application and another. --If the two objects are equal by the equals (Obeject) method, the hashCode method call on each of the two objects must produce the same integer result. --If the two objects are not equal to the equals (Object) method, it is not required that the hashCode method call on each of the two objects must produce different integer results. However, programmers should be aware that producing different integer results for unequal objects may improve the performance of hashtables.

hashCode override example


    //[Good example] hashCode override example
    @Override
    public int hashCode() {
        int result = Short.hashCode(areaCode);
        result = 31 * result + Short.hashCode(prefix);
        result = 31 * result + Short.hashCode(lineNum);
        return result;
    }

―― 31 is an odd prime number and is traditionally chosen because of its good performance. --Guava's Hashing has few collisions. ――The hashCode below does boxing / unboxing, so the performance is not very good.

HashCode method automatically generated by IntelliJ


    @Override
    public int hashCode() {
        return Objects.hash(areaCode, prefix, lineNum);
    }

Item 12 Always override toString

--For all instantiable classes you create, override the Object toString implementation if the superclass hasn't already overridden it. ――It makes the class easier to use and useful for debugging. --The toString method should return a concise and useful description of the object in an aesthetic and nice format.

Item 13 Carefully override clone

--The Cloneable interface indicates that the class allows replication. --Object's clone method is protected, but classes that implement Cloneable are expected to provide a well-functioning public clone method. --Clone should not be provided because immutable classes make useless duplicates.

Clone method of a class that has no reference to a mutable state


//Implement Cloneable
public final class PhoneNumber implements Cloneable {
//abridgement
    @Override
    public PhoneNumber clone() {
        try {
            return (PhoneNumber) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError(); //Can't happen
        }
    }

Clone method of a class with a reference to a mutable state


public class Stack implements Cloneable {
//abridgement
    @Override
    public Stack clone() {
        try {
            Stack result = (Stack) super.clone();
            //Clone the array and put it in a member variable.
            result.elements = elements.clone();
            return result;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }

Item 14 Consider implementing Comparable

--The Compareable interface, which indicates that it has a natural order, has only one method, compareTo.

Comparable with comparator construction method


public final class PhoneNumber implements Comparable<PhoneNumber> {
//abridgement
    private static final Comparator<PhoneNumber> COMPARATOR =
            Comparator.comparingInt((PhoneNumber pn) -> pn.areaCode)
            .thenComparingInt(pn -> pn.prefix)
            .thenComparingInt(pn -> pn.lineNum);

    @Override
    public int compareTo(PhoneNumber pn) {
        return COMPARATOR.compare(this, pn);
    }

Recommended Posts

Effective Java 3rd Edition Chapter 3 Methods Common to All Objects
Effective Java 3rd Edition Chapter 8 Methods
Effective Java 3rd Edition Chapter 5 Generics
Effective Java 3rd Edition Chapter 9 Program General
Effective Java 3rd Edition Chapter 6 enums and annotations
Effective Java 3rd Edition Chapter 4 Classes and Interfaces
Effective Java 3rd Edition Chapter 7 Lambda and Streams
Effective Java 3rd Edition Chapter 2 Object Creation and Disappearance
I tried to explain Effective Java 3rd edition "almost all chapters" in "easy-to-read Japanese".
Effective Java Chapter 2
Effective Java Chapter 6 34-35
Effective Java Chapter 4 15-22
Effective Java Chapter 3
effective java 3rd summary
Effective Java 3rd Edition Section 85 Choose Alternatives Over Java Serialization
What has changed between Effective Java 2nd Edition and 3rd Edition
From Ineffective Java to Effective Java
[Read Effective Java] Chapter 2 Item 5 "Avoid the creation of unnecessary objects"
How to use class methods [Java]
[Effective Java] Avoid creating unnecessary objects
[Read Effective Java] Chapter 2 Item 1 "Consider static factory methods instead of constructors"
Convert all Android apps (Java) to Kotlin
[Read Effective Java] Chapter 2 Item 7 "Avoid Finalizers"
Inexperienced learning methods to get Java Silver 11