[JAVA] Différence entre l'opérateur == et la méthode égale

Au travail, un jeune homme m'a demandé "Pourquoi utilisez-vous" égal "au lieu de" == "(à ce moment, dans String), et nonchalamment" Comparez les objets en comparant les valeurs dans la méthode égale ". C'est le corps. " Cependant, pour être honnête, je ne l'ai compris que comme Zakuri, alors je suis retourné au début et j'ai fait des recherches. Puisque je suis de retour au début, je vais parler de l'histoire évidente. Et veuillez signaler toute erreur.

Types primitifs et de référence

Tout d'abord, Java est grossièrement divisé en types primitifs et types de référence. Les types primitifs stockent principalement des données et n'ont aucune méthode. Par conséquent, il est également appelé un type de données de base. La création d'une valeur de type primitif écrira la valeur directement dans la mémoire. Il existe les huit types primitifs suivants.

Vous pouvez considérer les types primitifs comme commençant par une minuscule. Tous les autres types commençant par une majuscule, y compris le type String, sont des types référence. Pour le type de référence, l'adresse de l'objet référencé est écrite dans la mémoire. Maintenant, je voudrais comparer ces derniers.

== opérateur

Comparons en fait le type primitif et le type de référence en utilisant int et Integer avec "l'opérateur ==".

//Comparaison des types primitifs
int intA = 1;
int intB = 1;
System.out.println(intA == intB); // ture

//Comparaison des types de référence
Integer integerA = new Integer(1);
Integer integerB = new Integer(1);
System.out.println(integerA == integerB); // false

Il semble que les valeurs soient comparées dans le type primitif. Il semble que les valeurs ne sont pas comparées dans le type de référence, et même si integerA et integerB doivent être identiques à 1, elles sont traitées comme false. Cela est dû au fait qu'il ne compare pas les valeurs contenues dans Integer, mais compare les instances référencées de l'entier A et de l'entier B pour déterminer si elles sont la même instance. En d'autres termes, lorsque vous comparez le type de référence avec "l'opérateur ==", les adresses de référence détenues par les variables sont comparées pour déterminer s'il s'agit de la même instance. La même valeur entre les variables (adresse de référence dans le cas du type de référence) est appelée valeur égale </ b>.

méthode égale

Je comprends les spécifications de fonctionnement de "l'opérateur ==". Mais je veux comparer les valeurs que j'ai en interne ... C'est là que la «méthode égale» entre en jeu.

//Comparaison des types de référence
Integer integerA = new Integer(1);
Integer integerB = new Integer(1);
System.out.println(integerA.equals(integerB)); // true

En utilisant la "méthode égale", il semble que vous effectuez une comparaison de valeur. Alors quel type de traitement est réellement effectué dans la méthode?

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*/

}

Je compare ma valeur (int) dans la méthode avec la valeur (int) de l'objet argument avec "l'opérateur ==". En d'autres termes, la valeur (type primitif) que vous voulez vraiment comparer dans la méthode est comparée à "l'opérateur ==". De cette façon, différentes instances mais la même valeur d'instances sont appelées équivalentes </ b>. Au fait, j'ai essayé de voir ce qui s'est passé dans le cas du type String.

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*/

}

Même avec le type String, la valeur interne (char []) est comparée caractère par caractère. À propos, si vous écrivez ce qui suit, le résultat sera légèrement différent.

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

Cela semble différent, mais en fait stringA et stringB sont la même "chaîne", ils sont donc réécrits pour faire référence à la même instance au moment de la compilation.

prime

Il existe également java.util.Objects # equals pour les comparaisons de valeurs.

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

La "méthode equals" de l'objet lui-même provoque souvent une NullPointerException, il peut donc être judicieux d'utiliser cette méthode.

finalement

En Java, il semble que le type primitif contienne la valeur des données et que le type de référence la référence. Si vous voulez comparer des données brutes (type primitif), utilisez "== operator", si vous voulez comparer des valeurs via le type de référence, utilisez "equals method" et laissez-les comparer "== operator" en interne. C'était embarrassant équivalent à la même valeur que Zakuri ... Je voudrais continuer à me consacrer chaque jour.

Recommended Posts