Recently after a big guy’s suggestion to prepare to read the JDK source code to improve their own so began to write JDK source code analysis article

Read JDK version 1.8


  • directory
    • Object diagrams
    • The constructor
    • The equals method
    • GetClass method
    • HashCode methods
    • The toString method
    • The finalize method
    • RegisterNatives method

1. Object structure diagram

2. Class constructor

A class constructor is one of the methods for creating Java objects. We usually use the new keyword for instances, and we can initialize them in the constructor. A constructor must exist in a Java class, and if it is not added, the system creates a no-parameter constructor by default at compile time.

*/ Object obj = new Object()Copy the code

3. The equals method

The equals() operator is used to compare whether values of basic types are the same and equals() is used to compare whether two objects are equal. The question arises as to how two objects are equal. Look at the equals implementation in object

 public boolean equals(Object obj) {
        return (this == obj);
    }
Copy the code

Equals and == are equivalent in Object. So if two objects in Object have the same reference, they must be identical. We must override equals when we customize our objects. To analyze the String override’s equals method, I refer to the following online source:


public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while(n-- ! = 0) {if(v1[i] ! = v2[i])return false;
                    i++;
                }
                return true; }}return false;
    }
Copy the code

A String is a reference type. Comparisons do not compare references for equality, but rather the contents of strings for equality. So the standard for the String class to define two objects equal is that the String content is the same.

In the Java specification, the use of equals must follow the following principles:

  • Reflexivity: x.equals(x) should return true for any non-null reference value x.
  • Symmetry: for any non-null reference values x and y, x.cube (y) should return true if and only if y.cube (x) returns true.
  • Transitivity: For any non-null reference values x, y, and z, x. quals(z) should return true if x. quals(y) returns true and y.quals (z) returns true.
  • Consistency: Multiple calls to x.equals(y) always return true or always return false for any non-null reference values x and y, provided that the information used in the equals comparison on the object has not been modified
  • For any non-null reference value x, x.equals(null) should return false


public class Student { private String name; /** * no argument constructor */ publicStudent() {} /** * public Student(String name) {this.name = name; } public StringgetName() {
        return name;
    }

    public void setName(String name) { this.name = name; } @override public Boolean equals(Object obj) {// Two objects must be the sameif(this==obj){
            return true; } // Student does not want to wait if the object is null or notif(obj==null || ! (obj instanceof Student)){return false; } // Convert to Student object Student Student = (Student)obj; // Returns the same attributetrue
        returnthis.getName()==student.getName(); }}Copy the code

Then create a test class to test:

        Student t1 = new Student("yes");
        Student t2 = new Student("slm");
        System.out.println("Different objects have different properties =="+(t1==t2));
        System.out.println("Different objects have different equals properties."+(t1.equals(t2)));
        Student t3 = new Student("slm");
        System.out.println("Different objects have the same properties"+(t2.equals(t3)));
Copy the code

Output result:

Different objects have different properties == False Different objects have different properties equals False Different objects have the same properties True

Now you can see that if you don’t override equals here, you will always only perform Object’s equals, which is to check whether the Object references the same address by ==. Now let’s do another example where we have a Student subclass and we’re comparing it

/** * @Author: sunluomeng * @CreateTime: 2019-06-06 23:35 * @Description: */ public class Language extends Student{ private String name; /** * no arguments */ publicLanguage@param name */ public Language(String name){this.name=name; } public StringgetName() {
        return name;
    }

    public void setName(String name) { this.name = name; } @override public Boolean equals(Object obj) {// Two objects must be the sameif(this==obj){
            return true; } // Student does not want to wait if the object is null or notif(obj==null || ! (obj instanceof Language)){return false; } // Convert to Student object Language Language = (Language)obj; // Returns the same attributetrue
        returnthis.getName()==language.getName(); }}Copy the code

At this point our newly created Language class inherits Student and creates two objects to compare

The parent class has the same attributes as the child class: true The child class has the same attributes as the parent class: false

Equals (language) and language.equals(student) return false

This violates the symmetry mentioned above

For any non-null reference values x and y, x. quals(y) should return true if and only if y.quals (x) returns true

If y is Student and x is Language, then y.quals (x) equals true and x.quals (y) should return true, but why false?

Let’s take a look at the code


The instanceof operator in Java is used to indicate at run time whether an object is an instanceof a particular class. Instanceof returns a Boolean value indicating whether the object is an instanceof this particular class or a subclass of it.

In this case, Language is a subclass of Student and returns true when using instanceof. Language is a subclass of Student and returns true when using instanceof. Language is a subclass of Student and returns true when using instanceof Student is also not a subclass of Language so it will return false. And the solution is

Then we run the output from the code we just created:

The parent class has the same properties as the child class. False The child class has the same properties as the parent class. False

Note: The use of getClass is situational; using getClass does not meet the definition of polymorphism

So when do you use Instanceof and when do you use getClass?

  • If subclasses can have their own notion of equality, symmetry requirements force getClass for detection.
  • If there is a notion that a superclass determines equality, then instanceof can be used for detection, so that objects of different subclasses can be compared for equality.

It’s also important to note that whenever you override this method, you usually have to override the hashCode method to maintain the general convention of the hashCode method, which states that equal objects must have the same hashCode.

4. GetClass method

Let’s first look at the implementation of getClass in Object.



For more information about Native, please visit Baidu. Native is implemented by the operating system for us


You can see that getClass returns a runtime object. You can see that the getClass method is final, indicating that this method cannot be overridden.

5.hashCode

Let’s take a look at the implementation of hashCode in Object:

HashCode is also a native method that is modified by native and the annotation says return the hash value of that object. So what does it do?

It is mainly designed to ensure that the collection based on hash, such as HashSet, HashMap and HashTable, can not be repeated when inserting elements. At the same time, it is designed to improve the efficiency of convenient insertion and deletion of elements. It is mainly for the ease of finding.

For example, use Set. The Set is non-repeatable, and if you compare every time you add data to equals, it’s very slow to compare 100,000 inserts to 100,000 times. So when you add data, you use a hash table, and the hash algorithm is also called a hash algorithm, and when you add a value, you compute its hash value and then you insert the data into the specified location based on that hash value. This avoids the productivity pitfalls of calling equals all the time. At the same time, the following conditions:

  • If the location is empty, add it directly
  • If the position is not empty, determine whether the two elements are the same; if they are, they are not stored.

There’s also a case where two elements are different, but the hashCode is the same, and that’s a hash collision. Create a linked list of the same elements if the hash key is the same. Store all the same elements in a linked list.

6.toString

Let’s look at the implementation of toString


7.finalize

Implementation method in the source code:

8.registerNatives

Source code implementation:

Notify ()/notifyAll()/wait() etc

The last

Little brother not just, if there is a mistake please point out. Like please pay attention to, slowly update the JDK source read notes ** little brother public number, disorderly knock code. Welcome to like, follow **