getClass() vs instanceof in equal (JAVA)

Компьютеры. программирование, бытовая техника

Модератор: Саша З.

Аватара пользователя
alexsmail
Ветеран мега-форума
Сообщения: 12637
Зарегистрирован(а): 28 дек 2004, 21:49
Откуда: Мединат hаеhудим
Контактная информация:

getClass() vs instanceof in equal (JAVA)

Сообщение alexsmail » 23 май 2005, 19:19

Мне пришлось написать метод equal для final class. Во время написания рагорелся спор нужно ли испоьзовать instanceof или getClass() в этот методе. Как не трудно увидеть. В этом случае это не важно, так как в этом случае это эквивалентно.
Однако, остаётся вопрос, как поступить в общем случае. Я предпринял поиск и на мое удивление я обнаружил, что нет единого мнения на сей счет. Также я обнаружил интересную переписку с одним из разбработчиков Sun на этот счет http://www.codeproject.com/useritems/Em ... print=true
Мой блог http://toalexsmail.com/

Лучшее - враг хорошего.

Великие умы обсуждают идеи, посредственные умы обсуждают события, недалекие умы обсуждают личности. Элеонора Рузвельт

Нужно воспитывать опрятность в мышлении.

Аватара пользователя
alexsmail
Ветеран мега-форума
Сообщения: 12637
Зарегистрирован(а): 28 дек 2004, 21:49
Откуда: Мединат hаеhудим
Контактная информация:

Re: getClass() vs instanceof in equal (JAVA)

Сообщение alexsmail » 23 май 2005, 20:48

alexsmail писал(а):I should reiterate that one can argue for both approaches. With the
instanceof approach, it's easy to write "trivial subclasses" and
impossible to add an aspect (a field used in equals comparisons). With
the getClass approach it's possible to add an aspect (assuming you're
willing to have the subclass instances not interact with the superclass
instances) but it is impossible to create a subclass that it is usable
anywhere the superclass is usable, even a "trivial subclass." While the
instanceof approach predominates, some respected authors do consider the
getClass approach to be acceptable.

One last thing worth mentioning is that this controversy is far less
important than it might appear. The vast majority of classes should not
override Object.equals at all. Only value classes (or other classes
with value semantics) should do so. Furthermore, most value classes
should be immutable, hence final. If a class is final, it doesn't
matter which of the two kinds of equals methods it has.

From a theoretical perspective, it is often suspect to add an aspect in
a subclass, as it often violates the "is-a" test. For example, some
books have a 3-dimensional point (Point3) subclass a 2-dimensional point
(Point2). However, it is *not* the case that a 3-dimensional point is a
2-dimensional point!..

Мой блог http://toalexsmail.com/

Лучшее - враг хорошего.

Великие умы обсуждают идеи, посредственные умы обсуждают события, недалекие умы обсуждают личности. Элеонора Рузвельт

Нужно воспитывать опрятность в мышлении.

AlexZ75
Участник со стажем
Сообщения: 1304
Зарегистрирован(а): 18 ноя 2001, 02:00
Откуда: Петах-Тиква
Контактная информация:

Сообщение AlexZ75 » 24 май 2005, 04:55

alexsmail,
Чтоб это было самой большой вашей проблемой (с)

Статья мне показалась несколько бредовой, особенно это:
I think Sun should remove interfaces from Java. And the rule should be "replace interfaces with abstract classes".

Interfaces result a problem, that is version not compatitable. Once you release a java interface, others use it, you can't modfiy it any more. Cause if you add a funtion to that java interface, others code can't compile. When you change to abstract classes, everything is ok, you can add new functions later freely.
Отличительная черта большинства туземцев - человеколюбие.

Аватара пользователя
Зяма Крендель
Ветеран мега-форума
Сообщения: 5327
Зарегистрирован(а): 21 июл 2003, 13:07
Откуда: Чикаго

Сообщение Зяма Крендель » 24 май 2005, 09:40

Эта фраза - "I think Sun should remove interfaces from Java. And the rule should be "replace interfaces with abstract classes" - на самом деле, недоговоренное "сделайте virtual machine для C++ и не мучайтесь"... :ic1:

По теме - по-моему, это просто зависит от того, чего мы хотим добиться. Если сравнение с подклассом нас устраивает, это одно, если нет - тогда надо требовать полного совпадения (getClass().equals)... :13:
"...читает недоступную его пониманию философскую литературу, делает бессистемные выписки..."
© Учебник психиатрии, симптомы шизофрении

Аватара пользователя
alexsmail
Ветеран мега-форума
Сообщения: 12637
Зарегистрирован(а): 28 дек 2004, 21:49
Откуда: Мединат hаеhудим
Контактная информация:

Сообщение alexsmail » 24 май 2005, 22:30

AlexZ75 писал(а):alexsmail,
Чтоб это было самой большой вашей проблемой (с)

Насчет большой проблемы, полностью с вами согласен :-) Просто, скажем, в С++ нет никакой проблемы с этим.

Статья мне показалась несколько бредовой, особенно это:
I think Sun should remove interfaces from Java. And the rule should be "replace interfaces with abstract classes".

Interfaces result a problem, that is version not compatitable. Once you release a java interface, others use it, you can't modfiy it any more. Cause if you add a funtion to that java interface, others code can't compile. When you change to abstract classes, everything is ok, you can add new functions later freely.


Вы не внимательно читали. Это не статья, это переписка. То, что вы процетировали это предложение некого программиста (кто это всё поместил сюда). А ответ на это в очень мягкой форме говорит, что это бред. :-)

ИМХО, статья хорошая. Я во многих местах видел спор на тему instanceof vs getClass() и никак не мог понять чего это тут огород городить.
Мой блог http://toalexsmail.com/

Лучшее - враг хорошего.

Великие умы обсуждают идеи, посредственные умы обсуждают события, недалекие умы обсуждают личности. Элеонора Рузвельт

Нужно воспитывать опрятность в мышлении.

Аватара пользователя
alexsmail
Ветеран мега-форума
Сообщения: 12637
Зарегистрирован(а): 28 дек 2004, 21:49
Откуда: Мединат hаеhудим
Контактная информация:

Сообщение alexsmail » 24 май 2005, 22:40

Зяма Крендель писал(а):
...По теме - по-моему, это просто зависит от того, чего мы хотим добиться. Если сравнение с подклассом нас устраивает, это одно, если нет - тогда надо требовать полного совпадения (getClass().equals)... :13:

Если равентсво предпологает прежде всего равенство типом, то тогда нужно использовать getClass() и нет никаких проблем.
Сам же автор говорит (перевод процетировагого во втором посте):
"Использую instanceof легко создать "тривиальные подклассы" и невозможно добавить аспект (поле, используемое при equals сравнении). Используя getClass() легко добавить аспект (который не пересекается с суперклассом), но не возможно создать подкласс, котором можно было пользоваться вместо суперкласса, даже "тривиальный подкласс."
Поэтому это также зависит от того добавляем ли мы новые поля в подкласс или нет, и хотим ли мы использовать подкласс вместо суперкласса. Для прояснение последнего момента в статья приводится пример с комплексными числами (наследование класса Complex).
Мой блог http://toalexsmail.com/

Лучшее - враг хорошего.

Великие умы обсуждают идеи, посредственные умы обсуждают события, недалекие умы обсуждают личности. Элеонора Рузвельт

Нужно воспитывать опрятность в мышлении.

AlexZ75
Участник со стажем
Сообщения: 1304
Зарегистрирован(а): 18 ноя 2001, 02:00
Откуда: Петах-Тиква
Контактная информация:

Сообщение AlexZ75 » 27 май 2005, 07:29

alexsmail,
Вы понимаете что есть разница в instanceOf и getClass().equals?
Отличительная черта большинства туземцев - человеколюбие.

Аватара пользователя
alexsmail
Ветеран мега-форума
Сообщения: 12637
Зарегистрирован(а): 28 дек 2004, 21:49
Откуда: Мединат hаеhудим
Контактная информация:

Сообщение alexsmail » 27 май 2005, 16:33

AlexZ75, естествеено. getClass() возвращает динамический (Runtime) тип объекта, instanceof проверяет можно ли привести без casting тип объекта к заданному.
Пример:
class Father{...}
class Son extends Father {...}
Father o=new Son();

o.getClass().getName() - is "Son"
o instanceof Son - is true
o instanceof Father - is true
Мой блог http://toalexsmail.com/

Лучшее - враг хорошего.

Великие умы обсуждают идеи, посредственные умы обсуждают события, недалекие умы обсуждают личности. Элеонора Рузвельт

Нужно воспитывать опрятность в мышлении.

AlexZ75
Участник со стажем
Сообщения: 1304
Зарегистрирован(а): 18 ноя 2001, 02:00
Откуда: Петах-Тиква
Контактная информация:

Сообщение AlexZ75 » 06 июн 2005, 13:03

Ну тогда как можно сравнивать несравнимые вещи?
Отличительная черта большинства туземцев - человеколюбие.

Аватара пользователя
alexsmail
Ветеран мега-форума
Сообщения: 12637
Зарегистрирован(а): 28 дек 2004, 21:49
Откуда: Мединат hаеhудим
Контактная информация:

Сообщение alexsmail » 07 июн 2005, 21:12

AlexZ75, это реплика собственно на какой пост?
Мой блог http://toalexsmail.com/

Лучшее - враг хорошего.

Великие умы обсуждают идеи, посредственные умы обсуждают события, недалекие умы обсуждают личности. Элеонора Рузвельт

Нужно воспитывать опрятность в мышлении.

Аватара пользователя
alexsmail
Ветеран мега-форума
Сообщения: 12637
Зарегистрирован(а): 28 дек 2004, 21:49
Откуда: Мединат hаеhудим
Контактная информация:

Сообщение alexsmail » 22 июл 2007, 11:05

Мне понадобилось написать метод equals и смутно помнил, что есть проблема с instanceof, а какая не помнил. Дал поиск по google и нашёл эту тему. :70:
Мой блог http://toalexsmail.com/

Лучшее - враг хорошего.

Великие умы обсуждают идеи, посредственные умы обсуждают события, недалекие умы обсуждают личности. Элеонора Рузвельт

Нужно воспитывать опрятность в мышлении.

Аватара пользователя
TILIM
Участник форума
Сообщения: 43
Зарегистрирован(а): 01 дек 2005, 13:23
Контактная информация:

Сообщение TILIM » 22 июл 2007, 14:28

Если важна performance, я сравнил бы первый и второй вариант. Прогнал бы каждый в цикле 1000.000 раз и сравнил бы время.

Аватара пользователя
alexsmail
Ветеран мега-форума
Сообщения: 12637
Зарегистрирован(а): 28 дек 2004, 21:49
Откуда: Мединат hаеhудим
Контактная информация:

Сообщение alexsmail » 22 июл 2007, 18:36

TILIM, с точки зрения performance instanceof это катастрофа при работе с большими иерархиями. Лично я удивляюсь, что им так часто пользуются. Во-первых, нужно время, чтобы поднятся вверх по иерархии классов, для сравнения. Во-вторых, если ответ false, то генерируется СlassCastException, что очень дорого. Пусть A a; B b; a instanceof B эквивалентно (и так этот оператор работает реально)
try {
(B)a;
return true;
} catch(СlassCastException e){
return false;
}
Мой блог http://toalexsmail.com/

Лучшее - враг хорошего.

Великие умы обсуждают идеи, посредственные умы обсуждают события, недалекие умы обсуждают личности. Элеонора Рузвельт

Нужно воспитывать опрятность в мышлении.

Аватара пользователя
TILIM
Участник форума
Сообщения: 43
Зарегистрирован(а): 01 дек 2005, 13:23
Контактная информация:

Сообщение TILIM » 22 июл 2007, 20:17

alexsmail писал(а):TILIM, с точки зрения performance instanceof это катастрофа при работе с большими иерархиями. Лично я удивляюсь, что им так часто пользуются. Во-первых, нужно время, чтобы поднятся вверх по иерархии классов, для сравнения. Во-вторых, если ответ false, то генерируется СlassCastException, что очень дорого. Пусть A a; B b; a instanceof B эквивалентно (и так этот оператор работает реально)
try {
(B)a;
return true;
} catch(СlassCastException e){
return false;
}


А есть где-то код, выполняющий instanceof? В каком классе он реализован?

AlexZ75
Участник со стажем
Сообщения: 1304
Зарегистрирован(а): 18 ноя 2001, 02:00
Откуда: Петах-Тиква
Контактная информация:

Сообщение AlexZ75 » 22 июл 2007, 21:37

alexsmail,
Прошло более чем два года! :27:
Ни разу не было у меня проблем перформанс из-за пользвания instanceOf.
try {
(B)a;
return true;
} catch(СlassCastException e){
return false;
}

Тут есть логическая ошибка: любо подниматься по иерархии не надо (тогда Exception можно исключть), либо писать это...

Вообще если equals становиться проблемой перформанс из-за instanceOf ложите код в мусорку и возвращайтесь к дизайну. Сравнивать
getClass() vs instanceof in equal (JAVA)
глупо, все равно что запорожец с гранатометом. :19:
Отличительная черта большинства туземцев - человеколюбие.

observer
Ветеран мега-форума
Сообщения: 20931
Зарегистрирован(а): 08 фев 2003, 05:35

Сообщение observer » 23 июл 2007, 09:12

TILIM писал(а):А есть где-то код, выполняющий instanceof? В каком классе он реализован?

Это оператор. Он реализован в JVM.

Alf
Участник форума
Сообщения: 61
Зарегистрирован(а): 13 авг 2002, 04:50
Откуда: Израиль

Сообщение Alf » 23 июл 2007, 14:15

ИМХО использование instanceof - признак неудачного дизайна программы или иерархии классов.
Полиморфизм позволяет правильно работать с дочерними классами через ссылку на родительский класс без дополнительной проверки.
Спускаясь к Великой Реке, мы все оставляем следы на песке... ("Машина времени")

Аватара пользователя
alexsmail
Ветеран мега-форума
Сообщения: 12637
Зарегистрирован(а): 28 дек 2004, 21:49
Откуда: Мединат hаеhудим
Контактная информация:

Сообщение alexsmail » 23 июл 2007, 15:39

Alf писал(а):ИМХО использование instanceof - признак неудачного дизайна программы или иерархии классов.
Полиморфизм позволяет правильно работать с дочерними классами через ссылку на родительский класс без дополнительной проверки.

Полностью согласен. За исключением функций, которые должны по той или иной причине принимать Object. Как equals().
Вот похожею проблему с compareTo() в Java 1.5 удалось решить с помощью generic. (Там ClassCastException мог случится).
Мой блог http://toalexsmail.com/

Лучшее - враг хорошего.

Великие умы обсуждают идеи, посредственные умы обсуждают события, недалекие умы обсуждают личности. Элеонора Рузвельт

Нужно воспитывать опрятность в мышлении.

Alf
Участник форума
Сообщения: 61
Зарегистрирован(а): 13 авг 2002, 04:50
Откуда: Израиль

Сообщение Alf » 24 июл 2007, 08:42

alexsmail писал(а):Полностью согласен. За исключением функций, которые должны по той или иной причине принимать Object. Как equals().
Вот похожею проблему с compareTo() в Java 1.5 удалось решить с помощью generic. (Там ClassCastException мог случится).

Да, generic мощная штука (в умелых руках). Не зря он перекочевал из С++ в C# и Java. Честно говоря, не ожидал. :ic1:
Спускаясь к Великой Реке, мы все оставляем следы на песке... ("Машина времени")

Аватара пользователя
alexsmail
Ветеран мега-форума
Сообщения: 12637
Зарегистрирован(а): 28 дек 2004, 21:49
Откуда: Мединат hаеhудим
Контактная информация:

Сообщение alexsmail » 26 июл 2007, 14:07

После того, как я убедил себя (прочитав сообщение 2005 года в 2007 году :37: ) что использовать getClass() в equals() не есть good, я решил поискать как нужно правильно писать equals() с instanceof даже в том случае, когда добавляется новое поле. См. http://forum.java.sun.com/thread.jspa?threadID=5199295
Мой блог http://toalexsmail.com/

Лучшее - враг хорошего.

Великие умы обсуждают идеи, посредственные умы обсуждают события, недалекие умы обсуждают личности. Элеонора Рузвельт

Нужно воспитывать опрятность в мышлении.


Вернуться в «Наука и техника»




  Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 48 гостей