| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > Некорректная имплементация equals() |
| Автор: Royan 17.10.2007, 22:52 | ||
Есть класс
У кого-нибудь есть идеи почему это некорректная имплементация equals? Подчеркну, что речь идет именно о реализации метода equals(), а не о том, что тут не переписан hashCode() |
| Автор: Platon 17.10.2007, 22:57 | ||
Добавлено через 44 секунды Ты, наверно, имел ввиду переопределение. |
| Автор: Royan 18.10.2007, 00:00 |
| Верно сообразил. Молодец Platon +1 за внимательность. |
| Автор: Platon 18.10.2007, 00:02 |
| Че-то седня ты целый день вопросами сыпешь ;) я так с тобой авторитетным челом стану |
| Автор: fixxer 18.10.2007, 09:11 | ||||||
ClassCastException не боитесь поймать?
|
| Автор: Platon 18.10.2007, 09:18 |
| И правда что!! Приношу свои извинения, абсолютно правильная поправка. |
| Автор: Royan 18.10.2007, 09:35 |
| fixxer, Да абсолютно верно это тоже надо учитывать. |
| Автор: mindflyer 18.10.2007, 10:10 | ||||
ClassCastException уже боимся, надо бы ещё и NPE забояться в
|
| Автор: Shaggie 18.10.2007, 10:34 |
| Ээй, хватит! Так вы на этом участке скоро и OutOfMemoryException перехватывать будете! А Null успешно ловится на проверке instanceof, так что это, право, лишнее. |
| Автор: Royan 18.10.2007, 11:05 |
| Shaggie Справделивости ради OutOfMemoryError, а не exception... ну и я думаю никому не надо объяснять что error'ы никто не ловит, на то они и Error'ы |
| Автор: Shaggie 18.10.2007, 11:48 |
| Не-а. Exception. И его можно перехватить и обработать. Столкнулся с ним при работе с картинками - распакованные в памяти jpeg занимают очень много места, стандартных 64 мегабайт кучи не хватает и вылетает Exception. http://www.google.ru/search?q=java+outofmemoryexception&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ru:official&client=firefox-a |
| Автор: Royan 18.10.2007, 12:13 |
| Shaggie, Еще разок в JavaAPI такого Exception'а нет, Он может появиться только если его кто то написал для своих никому неведомых целей, а гугл иногда говорит глупости |
| Автор: Shaggie 18.10.2007, 12:28 |
| Так... а http://onesearch.sun.com/search/onesearch/index.jsp?charset=utf-8&col=all-filtered&qt=outofmemoryexception&y=0&x=0&cs=false&rt=true тоже глупости говорит? |
| Автор: chief39 18.10.2007, 12:32 |
| Гы |
| Автор: fixxer 18.10.2007, 14:34 | ||||
И? В данном случае методы this.name не вызываются и NPE не случится. Все корректно отработает. |
| Автор: mindflyer 18.10.2007, 15:46 | ||
fixxer, Shaggie, для тех, кто не боится NPE:
|
| Автор: fixxer 18.10.2007, 16:06 |
| Согласен. |
| Автор: Royan 18.10.2007, 16:36 |
| Shaggie, Ты скажи, что пытаешься доказать? Что такой класс есть JavaAPI? Такого класса там нет! То что на сановых форумах поиск выводит OutOfMemoryException то это только лишь от того что многие его участники забывают, что OutOfMemory бывает только Error и пишут по привычке Exception |
| Автор: chief39 18.10.2007, 17:55 | ||
Разница в инстансоф и сравнении по getClass ну и.... нуллы - э то нуллы. Они есть и будут есть. Зачем такой абстрактный иквалз нужен? Сферический конь в вакууме или принцесса, которая не какает. |
| Автор: mindflyer 19.10.2007, 08:57 |
Точно! Во тема, блин Вопрос не по теме, но зачем сделано через отрицания в "return !(str != null ? !str.equals(tmp.str) : tmp.str != null);"? Исходя из каких-то соображений? |
| Автор: jsse 19.10.2007, 09:16 | ||
| (offtopic) нигилизм наверное ) Добавлено @ 09:29 Если уже сильно нада сравнить, то я бы сделал так:
|
| Автор: Shaggie 19.10.2007, 09:36 |
| Royan, ок, принято. Свою ошибку признаю. Дома потестил - в самом деле Error вылетает, так что невнимательность на мне. |
| Автор: mindflyer 19.10.2007, 11:11 |
Механизм exception работает очень медленно по сравнению с обычными проверками (if, instanceof,...), не знаю какова разница в современной java, но про 1.4 видел в литературе высказывание о простых случаях (как рассматриваемый в этом топике) - "в десятки раз медленнее". |
| Автор: jsse 19.10.2007, 11:37 |
| mindflyer, я описал ситуацию если нужно очень получить ответ, но не скорость выполнения ), хотя было бы интересно узнать факты и примеры где Exсeption отрабатует "в десятки раз медленнее"! |
| Автор: chief39 19.10.2007, 11:46 | ||||
Оптимизейшн.
Вообще, эксепшн - это когда идёт что-то не так по нашей или чужой вине. "Соломка подстеленная на всякий случай". А управление нормальным ходом программы с помощьюэксепшнов - плохой стиль. Всё равно как вместо if(obj == null){ <blah-blah> } писать try{ if(obj.getName == "ewe") }catch(NullPointerException e){ <blah-blah> } Суть ни капли не меняется, но читать удобнее и правильнее |
| Автор: jsse 19.10.2007, 11:56 |
| chief39, еще хуже стиль когда в каждом сравнении типа if идет return |
| Автор: chief39 19.10.2007, 12:02 | ||
То есть? Типа: return x!=5; да? А что тут хуже? В том, что сразу "разбираются" тупиковые ветки алгоритма и бесповоротно "отсекаются" ретурнами? Для того, чтоб в конце блока случайно не наткнуться на давно забытое в начале. То бишь, есть претензии по варианту с несколькими ретурнами? Можно пояснить свою личную точку зрения? |
| Автор: jsse 19.10.2007, 12:11 |
| chief39, обычно код одной ф-ции не занимает 5 строк ) Например сложно будет читать код в котором 10 return на 20 строк кода. |
| Автор: Shaggie 19.10.2007, 12:36 | ||
Ща пофантазирую... 10 return - это 10 различных (!) ситуаций, из-за которых выполнение функции может завершиться досрочно. Причём не все они выбрасывают исключение. Значит, надо для отслеживания некоторых ситуаций писать собственные исключения. Если мы вместо 10 возвратов используем один большой трай-кетч блок, то сразу потеряем возможность отслежить причину выброшенного исключения, чтобы соответствующим образом отреагировать. А если используем 10 разных трай-кетч блоков, причём вложим их так, чтобы при вылетании исключения выполнение метода завершалось с нужным нам результатом, то можно будет в паспорте в графе "национальность" вписывать "индус". Предпочитаю честные возвраты. |
| Автор: jsse 19.10.2007, 13:11 |
| Shaggie, хаха! посмеялся +1. Я еще раз повторюсь - один из вариантов который я предложил, чтоб избежать ошибок - завернул в "Exception", но конечно, скорее всего, лучше было бы получить с помощью сравниния всевозможных ситуаций, и возможно, это правильней и производительней ) Всё равно как ни крути любая программа содежит минимум 3 ошибки. А на счет return в середине блока, даже в книге Шилдта и Нортона, которых стояли у истоков языка, не рекомендовали использовать возврат в середине функции. Да и как по мне, сложнее читать чужой код когда ищешь где функция должна вернуть тебе ответ, согласитесь гораздо проще увидеть что на входе(вызов функции) и что на выходе(возврат - return). |
| Автор: fixxer 19.10.2007, 13:16 |
| Шилдт и Нортон попсовики-писатели, им все равно про что боянить Java, C++, .Net |
| Автор: Shaggie 19.10.2007, 13:20 |
| В книге Джоша Блоха "Effective Java" в главе посвящённой equals он как раз не гнушается использовать возвраты точь в точь как chief39. А ведь товарищ - архитектор Java, его фамилию можно наблюдать в исходных кодах. Каждому своё. |
| Автор: jsse 19.10.2007, 13:21 |
| Что значит попсовики-писатели?? Добавлено через 4 минуты и 40 секунд Shaggie, конечно - это то же что и обсуждать стиль написания программы. каждому своё, но есть стандарты. Добавлено через 11 минут и 42 секунды Shaggie, Книгу конечно полистаю "Effective Java: Programming Language Guide By Joshua Bloch" |
| Автор: jsse 19.10.2007, 13:39 |
| Shaggie, где можно взять русский перевод? |
| Автор: mindflyer 19.10.2007, 14:28 | ||
Как пишет Мартин Фаулер (и я с ним полностью согласен на основе своего опыта) идея одной точки выхода (избегание возвратов в разных местах функции) - очень эффективна в рамках концепции структурного программирования. Однако, java это уже ООП, в котором размер методов как правило невелик, и обычно гораздо проще понимать код, когда выход из функции происходит именно в тот момент (в той точке), когда становится ясно, что дальнейшая его работа уже не нужна. Потому лично я сторонник стиля, о котором пишет chief39 |
| Автор: chief39 19.10.2007, 15:21 | ||
Обычно методы(не функции! это важно в данном контексте) по сути и не требуют десяти ретурнов. Но требют по логике работы парочки throw. Т.к. могут быть неопределённости в процессе выполнения. А супербольшие методы - это уже зло. А вот методы, подобные иквалз и хэшкод - довольно специфичны по задаче своей. Большинство методов работают с какими-то осмысленными крупнозернистыми операциями. А такие сервис-методы имеют задачей "проверить все поля и сказать ДА или НЕТ". Упомянутые недавно КА этим и занимаются. И лучше оптимизировать, дабы не танцевать вокруг всего объекта, если по первому пропери уже ясно что ОБЪЕКТ НЕ КАНАЕТ. Джавасоздатели зачем-то сделали короткое замыкание в логических выражениях По логике А: "тэк, взяли объект, ага.. он налл - всё, до свиданья! Не налл? Аха.. проверяем дальше, что там в следующем проперти? ...." По логике В: "взяли. попробовали. налл. эксепшн. так. теперь пошли ловить эксепшн. ага, поймали, выходим." Или ещё лучше: "ага, налл.. запишем в переменную метода. так, пошли дальше, дальше, дальше, дальше... ага. конец. тааак... что там с переменной? ага.. не подошло ещё в саомм начале... тэээк-с.. начинаем выходить из метода". Красиво, кто ж спорит |
| Автор: nornad 19.10.2007, 16:39 |
| Имхо, дискуссия на тему throw/if-return не имеет смысла. Оба имеют свои пределы применения, обоими можно злоупотреблять. Не будете же вы все if заменять на throw. И наоборот. Так чего спорить-то? Предпочитаете кидать эксепшены - кидайте. Если переборщите, сами услышите "запах" кода. То же самое и в обратном направлении. |
| Автор: w1nd 21.10.2007, 03:35 | ||||||
Вот правильно реализованный метод equals()
Во-первых, метод equals() не должен породить NullPointerException, если аргумент == null. Читаем javadoc:
Во-вторых, если вы используете instanceof вместо однозначной идентификации класса, вам стоит сделать метод equals() финальным. Потому что в ином случае наследник вашего класса может нарушить одно важное правило:
|
| Автор: Shaggie 22.10.2007, 05:47 |
В инете - не знаю, а в книжном видел за 280 р., попробуй поискать. Чуть не купил... денег с собой не было. Красноярск. |
| Автор: LSD 22.10.2007, 08:56 | ||
Причем сами создатели JDK нарушают это правило Добавлено через 4 минуты и 14 секунд Хотя по мне, реализация через getClass() не самая лучшая. |