Java object-oriented equals method, hashCode method, toString method and finalize method

Keywords: Java

1. Object class

1.1. equals method

1.1.1 comparison of = = and equals

==Is a comparison operator
==: you can judge both the basic type and the reference type
==: if the basic type is judged, whether the values are equal is judged
==: if the reference type is judged, whether the addresses are equal is judged, that is, whether the same object is judged
equals: it is a method in the Object class. You can only judge the reference type
The default judgment is whether the addresses are equal. This method is often overridden in subclasses to judge whether the contents are equal

package Equals01;

public class Equals01 {
    public static void main(String[] args) {
        A a = new A();
        A b = a;
        A c = b;
        System.out.println(a == c);  // true
        System.out.println(b == c);  // true

        B bObj = a;
        System.out.println(bObj == c);  // true
        int num1 = 10;
        double num2 = 10.0;
        System.out.println(num1 == num2);  // true, the basic data type to judge whether the values are equal

        // Jdk's source code equals of String class
        // The equals method of Object is rewritten to compare whether the two string values are the same
        /*
        public boolean equals (Object anObject){
            if (this == anObject) {  // If it is the same object
                return true;  // Return true
            }
            if (anObject instanceof String) {  // Judgment type
                String anotherString = (String) anObject;  // Downward transformation
                int n = value.length;
                if (n == anotherString.value.length) {  // If the length is the same
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {  // Then compare the characters one by one
                        if (v1[i] != v2[i])
                            return false;
                        i++;
                    }
                    return true;  // Returns true if all characters of two strings are equal
                }
            }
            return false;  // If the comparison is not a string, false is returned directly
        }
        */

        System.out.println("abc".equals("hello"));  // false

        /*
        // That is, by default, the equals method of Object is to compare whether the Object addresses are the same
        // That is to judge whether two objects are the same object
        public boolean equals(Object obj) {
            return (this == obj);
        }
        */

        // From the source code, we can see that Integer also overrides the equals method of Object
        // It becomes to judge whether the two values are the same
        /*
        public boolean equals (Object obj){
            if (obj instanceof Integer) {
                return value == ((Integer) obj).intValue();
            }
            return false;
        }
        */

        Integer integer1 = new Integer(1000);
        Integer integer2 = new Integer(1000);
        System.out.println(integer1 == integer2);  // false
        System.out.println(integer1.equals(integer2));  // true

        String str1 = new String("wcg");
        String str2 = new String("wcg");
        System.out.println(str1 == str2); // false
        System.out.println(str1.equals(str2)); // true
    }
}

class B {
}

class A extends B {
}
1.1.2. How to rewrite the equals method

Judge whether the contents of the two Person objects are equal. If the attribute values of the two Person objects are the same, return true, otherwise false

package Equals01;

public class EqualsExercise01 {
    public static void main(String[] args) {
        // Application example: judge whether the contents of two Person objects are equal. If the attribute values of two Person objects are the same, return true; otherwise, return false
        Person person1 = new Person("Zhang San", 18, 'male');
        Person person2 = new Person("Zhang San", 18, 'male');
        Person person3 = new Person("Li Si", 25, 'male');

        System.out.println(person1 == person2); // false
        System.out.println(person1.equals(person2));  // true
        System.out.println(person1 == person3);  // false
        System.out.println(person1.equals(person3));  // false
    }
}

class Person {
    private String name;
    private int age;
    private char gender;

    // Override the equals method of Object
    public boolean equals(Object obj) {
        // Judge whether the two objects compared are the same object, and return true directly
        if (this == obj) {
            return true;
        }
        // Type judgment
        if (obj instanceof Person) {  // It's Person
            // Make a downward transformation because I need to get the properties of obj
            Person p = (Person) obj;
            return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;
        }
        // If it is not Person, false is returned directly
        return false;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public Person(String name, int age, char gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
}

1.2. hashCode method

1.2.1 hashCode summary
  1. Improve the efficiency of containers with hash structure!
  2. If two references point to the same object, the hash value must be the same
  3. If two references point to different objects, the hash value is different
  4. The hash value is mainly based on the address number. The hash value cannot be completely equivalent to the address
1.2.2 code implementation
package HashCode_;

public class HashCode_ {
    public static void main(String[] args) {
        AA aa = new AA();
        AA aa2 = new AA();
        AA aa3 = aa;
        System.out.println("aa.hashCode()=" + aa.hashCode());  // aa.hashCode()=460141958
        System.out.println("aa2.hashCode()=" + aa2.hashCode());  // aa2.hashCode()=1163157884
        System.out.println("aa3.hashCode()=" + aa3.hashCode());  // aa3.hashCode()=460141958

        System.out.println(aa.equals(aa2));  // false
        System.out.println(aa.equals(aa3));  // true
        System.out.println(aa == aa2);  // false
        System.out.println(aa == aa3);  // true
    }
}

class AA {
}

1.3 toString method

1.3.1 definition
  1. Default return: hexadecimal of full class name + @ + hash value
  2. Subclasses often override the toString method to return the property information of the object
  3. When you override the toString method, the toString form of the object will be called automatically when printing or splicing objects
  4. When directly outputting an object, the toString method will be called by default, such as System.out.println(monster); Will be called by default
    monster.toString() method
1.3.2 code implementation
package ToString_;

public class ToString_ {
    public static void main(String[] args) {
        /*
        Object toString() source code
        (1)getClass().getName() Full class name of the class (package name + class name)
        (2)Integer.toHexString(hashCode()) Converts the hashCode value of an object to a hexadecimal string
        public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
        }
        */
        Monster monster = new Monster("goblin ", "Mountain patrolling", 1000);
        System.out.println(monster.toString() + " hashcode=" + monster.hashCode());

        System.out.println("==When outputting an object directly, toString Method is called by default==");
        System.out.println(monster);  // Equivalent monster.toString()

    }
}

class Monster {
    private String name;
    private String job;
    private double sal;

    public Monster(String name, String job, double sal) {
        this.name = name;
        this.job = job;
        this.sal = sal;
    }

    // Override the toString method to output the properties of the object
    // Use the shortcut keys to alt + insert

    @Override
    public String toString() {
        return "Monster{" +
                "name='" + name + '\'' +
                ", job='" + job + '\'' +
                ", sal=" + sal +
                '}';
    }
}

1.4. finalize method

1.4.1 definition
  1. When an object is recycled, the system automatically calls the finalize method of the object. Subclasses can override the method to release resources
  2. When to recycle: when an object has no reference, the jvm considers the object as a garbage object and uses the garbage collection mechanism to recycle it
    Destroy the object. Before destroying the object, the finalize method will be called first
  3. The call of garbage collection mechanism is determined by the system (that is, it has its own GC algorithm), or it can actively trigger the garbage collection mechanism through System.gc()
1.4.2 code implementation
package Finalize_;

public class Finalize_ {
    public static void main(String[] args) {
        Car bmw = new Car("bmw");
        // At this time, the car object is garbage. The garbage collector will recycle (destroy) the object and call the finalize method of the object before destroying the object
        // Programmers can write their own business logic code in finalize (such as releasing resources: database connection, or opening files...)
        // If the programmer does not override finalize, it will call finalize of the Object class, that is, the default processing
        bmw = null;

        System.gc();
        System.out.println("The program exited");
    }
}

class Car {
    private String name;

    // Properties, resources
    public Car(String name) {
        this.name = name;
    }

    // Override finalize
    @Override
    protected void finalize() throws Throwable {
        System.out.println("The car is being destroyed" + name);
        System.out.println("Some resources were released...");
    }
}

Posted by tomlei on Fri, 26 Nov 2021 05:45:11 -0800