Перегрузка Java объектами

Я хочу знать, почему второй оператор печати создает "одну реализацию", как и вывод, ниже приведен код Java

    class Point {
    public boolean equals(final Object anObject) {
        System.out.println("One implementation.");
        return false;
    }

    public boolean equals(final Point aPoint) {
        System.out.println("Another implementation.");
        return false;
    }
}

public class Main {
    public static void main(final String[] args) {
        final Point p1 = new Point();
        final Point p2 = new Point();
        final Object o = p1;
        System.out.println(p1.equals(p2));
        System.out.println(o.equals(p2));
        System.out.println(p1.equals(o));
    }
}

Выход:-

Другая реализация

ложный

Одна реализация {проблема}

ложный

Одна реализация

ложный

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
53
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Метод

boolean equals(Object other);

перегружает базовый метод объекта; Этот метод

boolean equals(Point other);

не. Итак, когда вы вызываете Object.equals(), что вы делаете во втором случае, вы попадаете в первую предоставленную вами реализацию. Переопределение Object.equals() — это то, что вам нужно сделать как минимум; другие реализации необязательны и, на мой взгляд, могут ввести в заблуждение.

Следует аннотировать переопределения с помощью @Override; это может помочь избежать путаницы в отношении того, действительно ли таковым является предполагаемое переопределение.

Вы можете использовать утилиту javap с флагами -c -v, чтобы лучше понять, что происходит, полная команда javap -c -v Main, ее вывод (я обрезал его)

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class Main$Point
       3: dup
       4: invokespecial #3                  // Method Main$Point."<init>":()V
       7: astore_1
       8: new           #2                  // class Main$Point
      11: dup
      12: invokespecial #3                  // Method Main$Point."<init>":()V
      15: astore_2
      16: aload_1
      17: astore_3
      18: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      21: aload_1
      22: aload_2
      23: invokevirtual #5                  // Method Main$Point.equals:(LMain$Point;)Z
      26: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
      29: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      32: aload_3
      33: aload_2
      34: invokevirtual #7                  // Method java/lang/Object.equals:(Ljava/lang/Object;)Z
      37: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
      40: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      43: aload_1
      44: aload_3
      45: invokevirtual #8                  // Method Main$Point.equals:(Ljava/lang/Object;)Z
      48: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
      51: return

Другими словами, компилятор Java преобразовал второй вызов в java/lang/Object.equals, потому что тип переменной oObject. Java является статически типизированным языком, поэтому все разрешения типов происходят во время компиляции, поэтому не имеет значения, будет ли переменная o назначена Point во время выполнения.

Другие вопросы по теме