Difference between == operator and equals method

At work, a young man asked me "Why do you use" equals "instead of" ==" (at this time, in String), and casually "Compare objects by comparing values in the equals method". It's the body. " However, to be honest, I only understood it as Zakuri, so I went back to the beginning and did some research. Since I'm back to the beginning, I'll talk about the obvious story. And please point out any mistakes.

Primitive and reference types

First of all, Java is roughly divided into primitive types and reference types. Primitive types mainly store data and have no methods. Therefore, it is also called a basic data type. When you create a primitive type value, the value is written directly to memory. There are the following eight primitive types.

Think of it as a primitive type that starts with a lowercase letter. All other types starting with an uppercase letter, including the String type, are reference types. For reference types, the address of the object that is referencing is written to memory. Now I would like to compare these.

== operator

Let's actually compare the primitive type and the reference type by using "== operator" using int and Integer.

//Primitive type comparison
int intA = 1;
int intB = 1;
System.out.println(intA == intB); // ture

//Reference type comparison
Integer integerA = new Integer(1);
Integer integerB = new Integer(1);
System.out.println(integerA == integerB); // false

It seems that the values are compared in the primitive type. It seems that the values are not compared in the reference type, and even though integerA and integerB should be the same 1, they are treated as false. This is because it is not comparing the values held inside Integer, but comparing the referenced instances of integerA and integerB to determine if they are the same instance. In other words, when you compare the reference type with the "== operator", the reference addresses held by the variables are compared to determine if they are the same instance. The same value between variables (reference address in the case of reference type) is called equivalence </ b>.

equals method

I understand the operating specifications of the "== operator". But I want to compare the values that I have internally ... This is where the "equals method" comes into play.

//Reference type comparison
Integer integerA = new Integer(1);
Integer integerB = new Integer(1);
System.out.println(integerA.equals(integerB)); // true

When I use the "equals method", it looks like I'm doing a value comparison. So what kind of processing is actually done in the method?

Integer.class


public final class Integer extends Number implements Comparable<Integer> {

    /*Omission*/

    private final int value;

    public int intValue() {
        return value;
    }

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

    /*Omission*/

}

The value (int) that I have in the method and the value (int) in the object of the argument are compared by "== operator". In other words, the value (primitive type) that you really want to compare in the method is compared with the "== operator". Such different instances but the same value of instances is called equivalent </ b>. By the way, I tried to see what happened in the case of String type.

String.class



public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /*Omission*/

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

    /*Omission*/

}

Even in the String type, the internal value (char []) is compared character by character. By the way, if you write the following, the result will be slightly different.

String stringA = "String";
String stringB = "String";
System.out.println(stringA == stringB); // true

This sounds different, but in fact stringA and stringB are the same "string", so they are rewritten to refer to the same instance at compile time.

bonus

For value comparisons, there is also java.util.Objects # equals.

String stringA = new String("String");
String stringB = new String("String");
String stringC = null;
System.out.println(java.util.Objects.equals(stringA, stringB)); // true
System.out.println(java.util.Objects.equals(stringA, stringC)); // false

The "equals method" of the object itself often causes a NullPointerException, so it might be a good idea to use this method.

Finally

In Java, it seems that the primitive type holds the data value and the reference type references it. If you want to compare raw data (primitive type), use "== operator", if you want to compare values via reference type, use "equals method" and let them compare "== operator" internally. Equivalence and equivalence were so basic that it was embarrassing to say that it was Zackri ... I will continue to devote myself every day.

Recommended Posts