简体   繁体   中英

Using the equals() method with String and Object in Java

Object o1 = new Object();
Object o2 = new Object();
//o1=o2;
System.out.println(o1.equals(o2));

It returns false . It can return true , if the comment is removed.


Why isn't the same thing applicable to the String class?

String s1=new String();
String s2=new String();
System.out.println(s1.equals(s2));

It returns true . Why? (because String uses interns or something else involved?)

Because equals() for String compares the content, not the object itself.

public boolean equals(Object anObject)

Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.

    /* String.equals() */
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = offset;
            int j = anotherString.offset;
            while (n-- != 0) {
                if (v1[i++] != v2[j++])
                    return false;
            }
            return true;
        }
    }
    return false;
}

(Link to the source of String.equals() )

Versus the equals for Object :

The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y , this method returns true if and only if x and y refer to the same object ( x == y has the value true ).

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

(Link to the source of Object.equals() )

Also, don't forget the contract of the equals() function:

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive : for any non-null reference value x , x.equals(x) should return true.
  • It is symmetric : for any non-null reference values x and y , x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive : for any non-null reference values x , y , and z , if x.equals(y) returns true and y.equals(z) returns true , then x.equals(z) should return true .
  • It is consistent : for any non-null reference values x and y , multiple invocations of x.equals(y) consistently return true or consistently return false , provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x , x.equals(null) should return false .

Also recommended reading:

equals for Object compares memory references.
That is why it is false since they are different Object s
equals for String is overridden to compare based on characters.
You have 2 empty String objects that is why equals returns true .

== compares addresses of the objects / strings / anything

.equals() designed to use internal state of the objects for comparison.

So:

new Object() == new Object() => false - two separate object at different addresses in memory.

new String("a") == new String("a") => false - the same situation - two separate addresses for the string objects.

new String("a").equals(new String("a")) => true - addresses differ, but Java will took one object state ('a') and compared with other object state ('a') will found them equal and will report true.

Using the equals() method you can code the comparison any way is proper for your program.

intern() is a bit different story. It is intended to return same object (address) for the same char sequence. It is useful to reduce amount of memory required when you have same strings constructed several times.

new String("aaa").intern() will seek in the machine memory if ever someone created "aaa" string before and will return the first instance of the String ... If non has been found - the current one will be enlisted as the first and all further "aaa".intern() and new String("aaa").intern() and ("a"+"aa").intern() will return that "first" instance.

Beware: "aaa".intern() is not very fast operation and if you will intern all strings - you will save some memory, but will loose quite a lot of CPU work.

The equals implemented in the Object class only compare references. Here is the source code:

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

equals method needs to be overridden inside the class if you want to make it behave in some other way. By default, it checks if two references refer to the same object.

The equals() Method of the Object class doesn't know how to compare Strings, it only knows how to compare objects. For comparing strings, a string class will override the equals() Method and compare strings in it.

Object.equals() will compare only references, where String.equals() will compare values.

Interesantly unlike the Sting the StringBuffer does not override the equals() method. Its functionality is the same as for the Object class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM