Java, почему должен равняться входному параметру метода быть Object - PullRequest
12 голосов
/ 09 июля 2011

Я изучаю книгу о структурах данных.В настоящее время я на графиках, и приведенный ниже код предназначен для вершинной части графика.

class Vertex<E>{
    //bunch of methods

    public boolean equals(Object o){
         //some code
    }
}

Когда я пытаюсь реализовать этот метод equals, мой компилятор жалуется на то, что он не проверяет тип параметра и просто разрешает посылать его любому объекту.Мне также немного странно, почему этот параметр не должен быть вершиной, а не объектом.Есть ли причина, по которой автор делает это, или это какая-то ошибка или устаревший пример?

Ответы [ 6 ]

15 голосов
/ 09 июля 2011
@Override
public boolean equals(Object obj)
{
     if(obj == null) return false;
     else if (!(obj instanceof Vertex)) return false;
     else return // blah blah
}
10 голосов
/ 09 июля 2011

равно (объект) это метод, определенный в корне - объект.Если вы не точно совпадаете с подписью, версия объекта будет вызвана, когда кто-нибудь проверит, равны ли два объекта.Не то, что вы хотите.

Возможно, вы видели другие методы (например, Comparator), в которых вы можете использовать точное время.Это связано с тем, что эти API были обобщены в Java 5. Равные не может быть, потому что можно вызывать equals с двумя отдельными типами.Он должен вернуть false, но это действительно.

3 голосов
/ 09 июля 2011

equals - это метод, унаследованный от Object, он определен как достаточно гибкий, чтобы вы могли взять любой объект и проверить, равен ли он любому другому объекту (как это должно быть по закону), и как это может быть любым другим способом?

Редактировать 1

Комментарий от jhlu87:
так что не стоит писать метод equals с входным параметром вершины?

Вы можете создать свою собственную перегрузку для любого метода, включая equals, но выполнение этого без изменения имени может привести к путанице со многими, которые будут считать, что ваши equals наследуются от Object. Если бы это был мой код, и я хотел бы использовать более конкретный метод equals, я бы назвал его немного отличным от просто «equals», чтобы избежать путаницы.

2 голосов
/ 09 июля 2011

Это потому, что этот метод существовал до обобщения, поэтому для обратной совместимости он должен оставаться таким.

Стандартный обходной путь для наложения типа:

return obj instanceof MyClass && <some condition>;
1 голос
/ 09 декабря 2018

Если ваш метод не принимает аргумент типа Object, он не переопределяет версию по умолчанию equals, а скорее перегружает его.Когда это происходит, обе версии существуют, и Java решает, какую из них использовать, основываясь на типе переменной (не фактическом типе объекта) аргумента.Таким образом, эта программа:

public class Thing {

    private int x;

    public Thing(int x) {
        this.x = x;
    }

    public boolean equals(Thing that) {
        return this.x == that.x;
    }

    public static void main(String[] args) {
        Thing a = new Thing(1);
        Thing b = new Thing(1);
        Object c = new Thing(1);
        System.out.println(a.equals(b));
        System.out.println(a.equals(c));
    }

}

сбивает с толку печатает true для первого сравнения (потому что b имеет тип Thing) и false для второго (поскольку c имеет тип Object, даже если это происходитсодержать вещь).

0 голосов
/ 09 июля 2011

Это потому, что автор имеет преимущество над равными. Равенство указано в java.lang.Object и является наследием всех классов.

См. Javadoc для java.lang.Object

...