Страницы

Поиск по вопросам

среда, 22 января 2020 г.

Переопределение equals() в анонимном классе с дополнительной переменной

#java


Например, создаю анонимный класс

new Object() {
    private int c;

    @Override
    public boolean equals(Object obj) {
        return c == (?cast?) obj.c;
    }
};


К чему я должен привсти obj?
    


Ответы

Ответ 1



На самом деле в java можно получить несколько объектов одного и того же анонимного класса, но вот воспользоваться этим анонимны классом для их сравнения не выйдет, потому что так они работают и с этим надо смириться))). Поэтому можешь не беспокоиться на этот счет, а если хочешь сравнивать разные экземпляры анонимных классов, зная что они по структуре своей одинаковые переопредели в них метод для получения хеш кода и переопредели equals так, чтобы он эти хеши сравнивал, приведу пример этой реализации первым. А потом будут примеры с анонимными классами MyAbstractClass obj = new MyAbstractClass() { public Integer a = 5; public String c = "sadfdsf"; @Override public int hashCode() { return a.hashCode() + c.hashCode(); } @Override public boolean equals(Object obj) { if (obj.getClass().isAnonymousClass() && obj instanceof MyAbstractClass) return this.hashCode() == obj.hashCode(); else return false; } @Override public String toString() { return this.getClass().getName(); } }; for (int i = 0; i < 20; ++i) { objects.add((MyAbstractClass) obj.clone()); } for (Object o : objects) { System.out.println(o + " " + obj.equals(o)); } Вот тут вывод, и пожелание не переопределять хешкод так, как это сделал я (просто суммировал хеши) а почитать про эту тему и выбрать более оптимальную реализацию. Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Ниже будут примеры с способами получить объекты одно и того же анонимного типа: public static void main(String[] args) throws IllegalAccessException, InstantiationException, CloneNotSupportedException { List objects = new ArrayList<>(5); MyAbstractClass obj = new MyAbstractClass() { public Integer a = 5; @Override public String toString() { return this.getClass().getName(); } }; for (int i = 0; i < 5; ++i) { MyAbstractClass obj2 = new MyAbstractClass() { public Integer a = 5; @Override public String toString() { return this.getClass().getName(); } }; objects.add(obj2); } for (Object o : objects) { System.out.println(o + " " + obj.getClass().equals(o.getClass())); } System.out.println(obj); } Вывод будет выглядеть как-то так: Solution$2 false Solution$2 false Solution$2 false Solution$2 false Solution$2 false Solution$1 Из него очевидно, что в теле цикла создавались объекты одного и того же анонимного класса и у них один тип, но анонимный класс описанный ранее, до входа в цикл имеет другое имя и соответственно это другой класс. Это работает таким образом потому что этот механизм схож с тем, как если бы java встречая в коде анонимный класс автоматически генерировала для него файл и объявляла его там как он описан в коде и сама присваивала ему имя по какому либо шаблону, а в коде оставляла ссылку на этот ею объявленный класс. Следующий пример: public static void main(String[] args) throws IllegalAccessException, InstantiationException { List objects = new ArrayList<>(5); Object obj = new Object() { public int a; @Override public String toString() { return this.getClass().getName(); } }; for (int i = 0; i < 5; ++i) { objects.add(obj.getClass().newInstance()); } for (Object o : objects) { System.out.println(o + " " + obj.getClass().equals(o.getClass())); } } Аналогичная ситуация. Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true Можно так же и клонированием, почему нет public class MyAbstractClass implements Cloneable { @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } } public static void main(String[] args) throws IllegalAccessException, InstantiationException, CloneNotSupportedException { List objects = new ArrayList<>(5); MyAbstractClass obj = new MyAbstractClass() { public int a; @Override public String toString() { return this.getClass().getName(); } }; for (int i = 0; i < 5; ++i) { objects.add((MyAbstractClass) obj.clone()); } for (Object o : objects) { System.out.println(o + " " + obj.getClass().equals(o.getClass())); } } Solution$1 true Solution$1 true Solution$1 true Solution$1 true Solution$1 true

Ответ 2



В Яве этот тип тебе не доступен. Более того, в твоём случае достаточно сравнить ссылки this и obj, потому что другого объекта с таким типом (кроме this) все равно не будет. Даже сли ты в следующей строке создашь такой же анонимный класс с таким же полем, с точки зрения Явы это будут два разных анонимных класса.

Комментариев нет:

Отправить комментарий