10
votes

Comment l'opérateur == est-il mis en œuvre en Java?

Spécifiquement, dans le cas de l'égalité de référence d'objet, que fait l'opérateur ==?

La comparaison renvoie-t-elle vrai si les références évaluent à la même adresse d'objet au moment de la comparaison? Ou utilise-t-il la valeur de code HashCode des deux références pour déterminer si les objets sont les mêmes?

Pour être très spécifique ici, j'aimerais savoir quelles structures de données gérées par la JVM sont référencées par l'opération == pour la comparaison de référence. Est-ce que == comptez sur le oop pour effectuer une comparaison de référence?

Malheureusement pour moi, le JLS fait Ne définissez pas comment l'opérateur == doit fonctionner . Les documents de l'API Java ne mentionnent pas ce que == est censé faire (ils sont pour les cours, non?)

PS: J'étais un peu intrigué par cette question sur Unicité de hashcode , et préférerait savoir comment la Sun JVM (ou OpenJDK) implémente l'opérateur ==.


0 commentaires

4 Réponses :


3
votes

Parce qu'une référence est juste un nombre, une comparaison de référence revient à comparer deux chiffres. Aucun hachage n'est nécessaire.


3 commentaires

La façon dont je comprends, la JVM stocke des informations sur chaque objet dans un OOP (pointeur d'objet ordinaire). J'aimerais savoir si l'opérateur == utilise ces informations ou non.


Pour le mettre dans de meilleurs mots, où la mise en œuvre == obtient cette valeur de référence pour l'utilisation en comparaison?


@Vineet: Consultez ma réponse pour plus de détails sur la manière dont le numéro est "généré" - le pointeur est un nombre.



2
votes

Le == compare les références d'objet à voir si elles sont identiques, c'est-à-dire. Ils se réfèrent au même objet en mémoire.

Le Equals () La méthode compare les références d'objet à voir si elles sont équivalentes, mais pas nécessairement identiques. L'implémentation par défaut de est égale () utilise l'opérateur == , mais il est souvent logique de remplacer ce comportement. Par exemple, vous voudrez peut-être que deux références de banqueCompteur soient considérées comme équivalentes si elles ont le même numéro de compte, même s'ils sont des objets complètement différents.


0 commentaires

10
votes

L'opérateur == compare simplement les références.

Les références dans le JVM ne sont qu'un pointeur d'objet standard. Cela fonctionne à une seule valeur entières 32 bits ou 64 bits (selon la plate-forme).

Lorsque vous comparez deux références d'objets, vous comparez vraiment deux entiers 32 bits ou 64 bits, et s'ils sont identiques, vous équivalez à égal. Les valeurs entières sont un emplacement en mémoire.


7 commentaires

Reed, je reçois ce que tu dis. Voudrais savoir où dans les sources JVM puis-je trouver la mise en œuvre de l'opérateur ==? Tous les indicateurs aideraient.


J'ai bien peur que cela entrave du territoire C / C ++.


Vous devriez regarder la mise en œuvre de Java.Lang.Object's Equals Méthode: Java.sun.com/j2se/1.3/docs/api/java/lang/...


Je crois qu'il y a un malentendu de mes commentaires. Si je me réfère à la mise en œuvre de la méthode Equals, je trouve une comparaison (cette == obj). En réalité, j'aimerais savoir où les pointeurs d'objet sont stockés par la JVM elle-même, de sorte que lorsque les adresses sont comparées, elles reviendront tristes ou faux.


Oops désolé. J'ai raté la partie où vous avez dit que les références sont des pointeurs d'objet standard. Cela implique-t-il que le JVM compare deux objets OOP pour la mise en œuvre ==?


Oui. Ce ne sont que des chiffres, car les pointeurs ne sont qu'une valeur INT spécifiant un emplacement de mémoire.


Je l'obtiens enfin. L'opération == se traduit par l'instruction IF_ACMPNE en bytecode; Au cours de l'exécution, cela éclate les références d'objet de la pile d'opérandes et les compare. Je n'ai toujours pas compris comment les références sont obtenues en premier lieu. Mais cela peut attendre.



0
votes

L'opérateur == retourne true si les objets sont le même objet. Il n'y a pas accès à hashcode () ou égaux () ici.

Essayez ceci pour confirmer: P>

public class Test {
    static void testEqualEqual(Integer I0, Integer I1, boolean IsEquals) {
        if(!(IsEquals == (I0 == I1)))
            throw new AssertionError();
    }
    static void testEqual(Integer I0, Integer I1, boolean IsEquals) {
        if(!(IsEquals == (I0.equals(I1))))
            throw new AssertionError();
    }
    static void testHash(Integer I0, Integer I1, boolean IsEquals) {
        if(!(IsEquals == (I0.hashCode() == I1.hashCode())))
            throw new AssertionError();
    }

    public static void main(String ... args) {
        testEqualEqual(   1,    1, true);
        testEqualEqual(2000, 2000, false);

        testEqual(   1,    1, true);
        testEqual(2000, 2000, true);

        testHash(   1,    1, true);
        testHash(2000, 2000, true);
        System.out.println("Done");
    }
}


2 commentaires

Merci, l'utilisation de la propriété en cache de la classe d'emballage entier était assez intelligente. Cependant, j'étais plus intéressé à connaître les classes et la structure de données réelles à l'intérieur de la JVM où la référence d'objet est stockée et éventuellement utilisée dans une opération de comparaison de référence.


Je vois ce que vous entendez maintenant, mais je crains que la réponse dépend de ce que JVM vous examine. Je pense que chaque JVM a une structure interne différente (bien que la mise en œuvre de la même spécification). Si vous voulez vraiment savoir, cédez le code source du OpenJDK télécharger.java.net/openjdk/jdk7 / "> OpenJDK >.: D