Interview Question Series Part 1: Tell me about the difference between == and equals? Your answer may be wrong

Recently, I am going to brush up on the interview questions, write a series of more classic and core content of the interview questions and publish them in the public account, consolidate the basic knowledge, and share with you. Welcome everyone to continue to pay attention to [Program New Vision]. The following is the first in this series.

The first question of most interviews is not to talk about object-oriented, or it is about characters. This article will talk about "the difference between == and equals" from all aspects.

Conceptual difference

For the comparison of strings (note that only strings), the difference between == and equals has the following two points:

(1) "==" is to judge whether two variables or instances point to the same memory space.

(2) "equals" is to judge whether the values ​​of the memory space pointed to by two variables or instances are the same.

The above description is rather obscure from the perspective of abstract concepts. In order to explain the above concepts clearly, let's first briefly understand the knowledge of JVM memory allocation.

Create the memory allocation of the object

In JVM, memory is divided into heap memory and stack memory. Normally, when we create an object through the new keyword, we call the object's constructor to open up space, store the object data in the heap memory, and at the same time generate a corresponding reference in the stack memory.

String str = new String("程序新视界");

In the above code, the real String object is stored in the heap memory, and the str variable only holds the reference address pointing to the object. When calling in subsequent code, all references in the stack memory (the address pointed to by str) are used.

How String implements equals method

After understanding the above concepts, let's take a look at how the equals method is implemented in String.

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;
}

The above code has two parts. The first part is to compare directly with "==". We already know whether the reference addresses of the comparison objects are equal. In other words, if the reference addresses of two objects are the same, then they are equal.

The second part of the code determines whether the incoming object is a String object. If it is a String object and each element in the char[] array of the values ​​of the two String objects is equal, then they are equal.

After reading the above code, you may understand why you need to add a note of "note only strings" when telling the difference between them. String's equals method compares values ​​because it overrides the equals method.

To summarize, the comparison of String can be shown in the following picture:

Interview String

We know that all classes in Java inherit from the Object object, and the equals method is also defined in the Object object:

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

What did we see? The equals method of Object turns out to be a reference address! Therefore, if you simply say that "==" compares by reference, equals compares by reference to the corresponding value, which is wrong! This is limited to the scope of the String class.

When we define a class, if the equals method is not overridden, the default equals method of Object is used. If you rewrite this method, compare it according to the rewritten method. The equals method of String is one of the rewritten examples.

Special String definition

In addition to being defined in the form of new, String can also be defined in the form of equal sign assignment:

String str = "程序新视界";

This is a very special form. Objects can be generated without new, which is essentially different from new. This form of assignment is called direct in Java, it exists in the constant pool, rather than stored in the heap like new.

When declaring such a string, JVM will first look for objects with corresponding values ​​in the constant pool. If so, assign it to the current reference, that is, the original reference and the current reference point to the same object. If not, a new object is created in the constant pool. For strings declared in this form, as long as the values ​​are equal, any multiple references point to the same object.

Creating a String object in contrast to the new form is the same as creating other objects. Each call generates a new object.

Example verification

The following concrete examples are used to verify the above conclusions. At the same time, these verification examples may also be the content of the interview questions.

String x = "程序新视界";
String y = "程序新视界";
String z = new String("程序新视界");

System.out.println(x == y); // true
System.out.println(x == z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true

The first line, because the object is created by assignment, when the object corresponding to x already exists in the memory, the reference is directly pointed to the original object when assigning the y object. Therefore equal.

In the second line, because z is created in the form of new, a new object will be created. Here, the reference addresses of the two objects are compared, so they are not equal.

The third and fourth lines compare the actual value of the string and are therefore equal.

Let's look at the comparison of objects without overriding the equals method. The corresponding entity class definition and unit test method are as follows:

@Test
public void testObject(){
	Person p1 = new Person("Tom");
	Person p2 = new Person("Tom");

	System.out.println(p1.equals(p2));
}

class Person{

	public Person(String name){
		this.name = name;
	}
	
	private String name;

	public String getName() {
		return name;
	}

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

Execute the above method, the printing result is false.

Through the above two examples, we have verified the theory we talked about above.

summary

After the above analysis, I understand the underlying logic, and I think everyone will be able to answer accurately when encountering similar interview questions.

Simply put, what is compared by equals is a reference, and what is compared by equals is a value. Strictly speaking, it is wrong. Only by solving the underlying implementation principles such as the storage form of the JVM object and rewriting the equals method can reflect your strength, rather than rote memorization.

In the next article, let's talk about the creation of several objects and underlying logic in the form of new String, welcome to continue to pay attention.

Original link: " Interview Question Series Part 1: Tell me about the difference between == and equals? Your answer may be wrong "


New Vision of Procedure

The public account " New Vision of Program ", a platform that allows you to simultaneously improve your soft power and hard technology, providing massive amounts of data

WeChat Official Account: New Vision of Program

Guess you like

Origin blog.csdn.net/wo541075754/article/details/108198289