First throw a question:
public static void main(String[] args) { System.out.println("string directly==:"+("qq"=="qq")); System.out.println("string equals distinguish:"+"qq".equals("qq")); String s1=new String("qq"); String s2=new String("qq"); System.out.println("string directly==:"+(s1==s2)); System.out.println("string equals distinguish:"+s1.equals(s2)); }
Output result:
string directly==:true string equals distinguish:true string directly==:false string equals distinguish:true
Brief description of the problem: The basic data type of the String class can use == and equals() to directly judge the content, but the object of the String class can use equals, but == fails.
Reason: == By default, only two things can be judged. For the basic data type, the value can be judged directly, and for the reference data type, the address code can be judged. The addresses of the two String objects are different (the two "qq" each have a location in the memory), == naturally fails.
As for how to judge the equality of two basic data types of the String class, the problem involving the constant pool is simply that when a certain string appears for the first time, its content and address are stored in the constant pool, and the same string is declared again. Call directly This one in the constant pool.
In this way, equals seems to be very flexible, as if it is not an object, but also can directly judge the content. So let's see how the other types do:
class User{ //Define a User class String name; int age; public User(String name, int age) { this.name = name; this.age = age; } public static void main(String[] args) { User u1=new User("qq",11); //Create two User objects User u2=new User("qq",11); System.out.println(u1.equals(u2)); //equals determines whether the objects are equal } }
Output result:
false
Reason: The source code of the equals method is as follows:
public boolean equals(Object obj) { return (this == obj); }
In other words, for general data types (we don't know if there is any subclass of Object that has overridden the equals method, but the class I wrote must not have overridden), calling equals is no different from using ==.
So why is String special? Let's look at the source code of the String class:
public boolean equals(Object anObject) { if (this == anObject) { return true; } return (anObject instanceof String aString) && (!COMPACT_STRINGS || this.coder == aString.coder) && StringLatin1.equals(value, aString.value);

We can see that the content (value/value) of the String object is an array of byte type at the bottom layer, and the String source code rewrites the equals method, and then judges the value after the == judgment. That is to say, the equals method of String can check the specific value.
Then let's look at one more:
String s1=new String("qq"); String s2=new String("qq"); Object o1=s1; //Upcast String object to Object Object o2=s2; boolean eo=o1.equals(o2); System.out.println("o1.equals(o2) is "+eo); Object o11=new Object(); //Create an Object object whose content is a String o11=1; Object o22=new Object(); o22=1; System.out.println("o11==o22 is "+(o11==o22)); System.out.println("o11.equals(o22) is "+o11.equals(o22));
Test Results:
o1.equals(o2) is true o11==o22 is true o11.equals(o22) is true
Brief description of the problem: Why can the Object class call the equals method to specifically determine whether the contents are equal?
Reason: As long as the subclass is rewritten, no matter whether it is the parent class object or the subclass object is called again, the subclass object will be called first.
It seems that the equals method is a bit tasteless. Programmers are very obsessed with this keyword, so they have to rewrite equals for different classes.
code show as below:
class User{ String name; int age; public User(String name, int age) { this.name = name; this.age = age; } public boolean equals(Object ano) { if(this==ano) { return true; } if (!(ano instanceof User)) { return false; } User anouser = (User) ano; //System.out.println("Parameter Downward Transformation———"+anuser); return name.equals(anouser.name)&&age==anouser.age; }
This code rewrites the equals method on User for the User class. The basic idea is to judge whether the attributes are equal one by one.
Specifically: Line 13 of the code indicates: If == is true, it means that the address codes of the two objects are the same, and the contents must be the same.
Line 16 of the code indicates: If the object ano used as a method parameter is not a User class, it must be different from the this object that calls this method.
The purpose of line 19 of the code is to convert ano down to User. After all, only the User class object can be equal to the User object. (Why can ano only be received according to the Object type? Because the rewriting method requires the method name, and the parameters are unchanged. When we use the User class as a parameter, it will automatically transform upwards to the Object class, which requires downward transformation. Of course, if Instead of rewriting the equals method, it is definitely possible to write a separate discrimination method for an object).
Line 21 of the code indicates: to determine whether the name attribute and the age attribute are equal.
Newcomers getting started, please give me a lot of advice.