75 votes

Code Java liées à la méthode equals

Je suis de pratiquer pour un examen, et a trouvé un exemple de problème que je ne comprends pas.

Pour le code suivant, trouvez tout ce dont la sortie est:

public class Test {

    private static int count = 0;

    public boolean equals(Test testje) {
        System.out.println("count = " + count);
        return false;
    }

    public static void main(String [] args) {
        Object t1 = new Test();
        Object t2 = new Test();
        Test t3 = new Test();
        Object o1 = new Object();

        ++count; t1.equals(t2);
        ++count; t1.equals(t3);
        ++count; t3.equals(o1);
        ++count; t3.equals(t3);
        ++count; t3.equals(t2);
    }
}

La sortie de ce code est - count = 4, mais je ne comprends pas pourquoi. Quelqu'un peut-il m'aider?

112voto

Eran Points 35360

La première chose à noter est que l' public boolean equals(Test testje) ne pas surcharger Objects' equals, étant donné que l'argument est - Test au lieu de Object, de sorte que les signatures ne correspondent pas à.

Par conséquent, l' main des appels de méthode equals(Test testje) exactement une seule fois - lors de l'exécution d' t3.equals(t3); - puisque c'est le seul cas dans lequel à la fois le type statique de l'instance equals est exécutée et le type de l'argument sont l' Test classe.

t3.equals(t3); est le 4 equals déclaration (qui vient après 4 incréments de la statique count variable), donc 4 est imprimé.

Tous les autres equals instructions sont exécutées Objects' equals, et donc l'impression de rien.

Une explication plus détaillée :

t1.equals() des appels Objects' equals quel que soit le type de l'argument, puisque la statique (à la compilation) type d' t1 est Object, et l' Test classe de ne pas surcharger cette méthode. L' Object de la classe n'a pas d' equals méthode avec un seul Test argument, equals(Test testje) ne peut pas être appelé, indépendamment de la dynamique (à l'exécution type) t1.

t3.equals() pouvez exécuter Objects' equals ou Tests'est égal, depuis le moment de la compilation type d' t3 est Test, et l' Test classe a deux equals méthodes (l'une héritée de l' Object la classe et les autres définis dans l' Test de la classe).

La méthode choisie dépend du moment de la compilation, le type de l'argument : 1. Lorsque l'argument est - Object (comme en t3.equals(o1); ou t3.equals(t2);), Objects' equals est appelé et rien n'est imprimé. 2. Lorsque l'argument est - Test, comme en t3.equals(t3);, les deux versions de l' equals match de cet argument, mais à cause des règles de la surcharge de méthode, la méthode la plus spécifique de l'argument - equals(Test testje) - est choisi et l' count variable est imprimé.

11voto

Stultuske Points 3948

La méthode equals dans le Test prend une instance de Test.

Toutes les tentatives précédentes ont été faites avec une instance de l'Objet, qui prennent la inherrited méthode de la classe Object:

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

Puisqu'il n'est pas de l'impression là-dedans, il ne sont pas imprimer n'importe quelle valeur.

Votre ++count; incrémente la valeur de compteur, de sorte que le moment où vous avez fait appel à votre

public boolean equals(Test testje){...

la méthode, qui n'imprimer que la valeur, la valeur de comptage est de 4.

7voto

t3.equals(t3) est la seule ligne qui a le droit arguments qui correspondent à la signature de la méthode public boolean equals (Test testje) donc c'est la seule ligne dans le programme qui fait les appels que l'instruction print. Cette question est destinée à vous apprendre quelques petites choses.

  • Toute la classe implicitement étendre Objet
  • Object.java contient une méthode equals qui prend type d'Objet
  • plusieurs méthodes avec le même nom ne peut exister à condition qu'ils aient des arguments différents - ce qui est connu comme la surcharge de méthode
  • la méthode de surcharge de la méthode qui est la signature correspond à la arguments au moment de l'exécution est la méthode qui est appelée.

Essentiellement, le truc c'est que le Test implicitement s'étend de l'Objet, comme toutes les classes java ne. Objet contient une méthode equals qui prend type d'Objet. t1 et t2 sont tapés telle qu'au moment de l'exécution, les arguments ne correspondent jamais à la signature de la méthode d'égal à égal qui est définie dans l'Essai. Au lieu de cela il est toujours à l'appel de la méthode equals dans Object.java parce que soit le type de base Est l'Objet dans lequel cas, les seules méthodes que vous avez accès sont celles définies dans Object.java ou le type dérivé est l'Objet auquel cas

public boolean equals(Test testje)

Ne peut pas être saisi, car dans ce cas au moment de l'exécution, l'argument est de type Object qui est une super-classe de Test, pas une sous-classe. Donc, au lieu de cela, il ressemble à la méthode equals dans le Test.java s'implicitement tapé super-classe Object.java qui contient aussi une méthode equals, qui arrive juste pour avoir une signature de la méthode de

public boolean equals (Object o)

dans ce cas, la hauteur de nos arguments lors de l'exécution afin que cette méthode equals est celui qui exécute.

Avis en cas de t3.equals(t3) à la fois le type de base et le type dérivé de la t3 Test.

Test t3 = new Test ();

cela signifie que lors de l'exécution, vous appelez la méthode equals dans Test.java et l'argument que vous êtes de passage dans est en fait de type de Test afin que les signatures de méthode de match et le code à l'intérieur Test.java exécute. À ce point - count == 4.

Bonus peu de connaissances pour vous:

@Override 

annotation vous peut-être vu dans quelques endroits explicitement indique au compilateur à l'échec si elle ne trouve pas la méthode avec la même signature quelque part dans une super-classe. C'est utile pour savoir si vous avez certainement l'intention de remplacer une méthode et vous voulez être absolument sûr que vous êtes vraiment substitution de la méthode et que vous n'avez pas accidentellement changé la méthode dans la super-classe ou sous-classe, mais pas les deux et Introduit une erreur d'exécution où la mauvaise mise en œuvre de la méthode est appelée à l'origine un comportement indésirable.

4voto

ABFORCE Points 3280

Il y a deux choses importantes que vous devez savoir.

  • Méthodes de remplacement doit avoir exactement les mêmes signatures que leur super-classe ont. (dans votre exemple, cette condition ne répond pas.)

  • En Java pour un objet, nous avons deux types: la compilation de type et d'exécution de type. Dans l'exemple suivant le type de compilation d' myobj est Object , mais son exécution est de type Car.

    public class Car{
          @Override
          public boolean equals(Object o){
                System.out.println("something");
                return false;
          }
    }
    

    Object myobj = new Car();

    Vous devriez noter que myobj.equals(...) résultats d'impression something dans la console.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X