День в истории Блогхауса: 23 мая 2018

Widowmaker1984, блог «Java для собеседований»

Вопрос 91 (метод finalize и сборка мусора)

"Что такое finalize? Зачем он нужен? Что Вы можете рассказать о сборщике мусора и алгоритмах его работы."

1. В некоторых объектно-ориентированных языках, в частности в C++, есть явные деструкторы, предназначенные для уничтожения объектов. Основная их задача — освобождение памяти, занятной объектами. Поскольку в языке Java реализован механизм автоматической сборки мусора, освобождать память вручную нет никакой необходимости, поэтому в языке Java деструкторы отсутствуют.

1.1. Разумеется, некоторые объекты используют кроме памяти и другие ресурсы, например файлы, или обрабатывают другие обьекты, которые в свою очередь, обращаются к системным ресурсам. В этом случае очень важно, чтобы ресурсы вовремя освобождались.В любой класс можно добавить метод finalize(). Этот метод будет вызван при первой сборке мусора следующей за моментом когда ваш объект стал недостижим.

скрытый текст2. Не стоит полагаться на finalize для чистки данных. Во-первых, нет гарантии, что он будет вызван, т.к. где-то может остаться ссылка на объект. Во-вторых, нет гарантии, в какое время будет вызван метод. Это связано с тем, что после того, как объект становится доступным для сборки и, если в нем переопределен метод finalize, то он не вызывается сразу, а помещается в очередь, которая обрабатывается специально созданным для этого потоком. Стоит отметить, что в очередь на финализацию попадают только те объекты, в которых метод finalize переопределен.

2.1. Есть вероятность, что данный метод не будет вызван совсем, т.к. программа завершит работу раньше.

2.1.1. Существует метод System.runFinalizerOnExit(true), гарантирующий, что метод finalize() будет вызван до того, как программа корректно завершит свою работу. Однако этот метод крайне ненадежен и не рекомендован к использованию. В качестве альтернативы можно применить метод Runtime.addShutdownHook(). Дополнительную информацию о нем можно найти в документации по API.

2.1.2. Есть другой способ быть уверенным, что finalize-методы были запущены для объектов, доступных для сборки: вызвать System.runFinalization() или Runtime.getRuntime().runFinalization().

2.2. Переопределение метода finalize значительно удлиняет время жизни объекта после смерти, так как он будет удален из памяти не раньше второй сборки мусора. А учитывая два первых пункта, если метод finalize у будет тяжелым иили таких объектов будет очень много, то объекты могут довольно долго висеть в фазе финализации и продолжать занимать место в памяти.

3. Интересной особенностью метода является то, что он может снова сделать объект доступным, присвоив this какой-нибудь переменной, хотя так делать не рекомендуется, т.к. при восстановлении объекта, повторно finalize вызван не будет.

3.1. Поэтому если по каким-то причинам очень надо воскресить данный объект, лучше внутри метода finalize создать его копию.

4. Одна из самых неприятных проблем возникающих при использовании метода finalize — это реордеринг. Представьте, что есть два объекта с переопределенным методом finalize, один из которых ссылается на другой. Так вот, если эти объекты стали недостижимы, то порядок вызова методов финализации произойдет в случайном порядке. Таким образом, у вас будет потенциальная опасность вызвать какой-нибудь метод на уже финализированном объекте из метода finalize другого объекта и получить ошибку.

5. Любые исключения выброшенные в теле метода будут проигнорированы.

5.1. Надо не забыть в конце метода вызвать super.finalize(). А учитывая предыдущий пункт, сделать это необходимо в блоке finally.

6. Согласно всему вышесказанному по возможности следует избегать использование метода finalize, вернее не стоит полагаться на него. Лучше освобождать ресурсы программно, а в методе finalize логировать, если этого почему-то сделано не было, чтобы вовремя найти и починить возникшую проблему. Также можно использовать его как последний шанс закрыть ресурс

6.1. Если ресурс должен быть освобожден сразу после его использования, нужно самостоятельно написать соответствующий код. Добавьте метод dispose() или close(), который нужно явно вызвать для очистки памяти. Если класс имеет такой метод, вы должны вызвать его по завершении работы с объектом этого класса. Недостатком является то, что разработчик должен помнить, что ресурс после использования нужно закрыть.

Catherine Montgomery, блог «я хотела бы знать»

so true

Волчица Юлия, блог «Театр и кино»

Любопытно, он будет только главой ЛВЧ или и сенсеем героя Хемсфорта тоже?

Снова новости со съемок новых Людей в черном. Они, кажется, берут в каст и Лиама Нисона :heart: Скажу так, одну из моих любимых франшиз кажется собираются переделывать НЕЖНО и качественно :red: Пока что весь каст вызывает мимими.

 

Звезда экшенов Лиам Нисон может присоединиться к Крису Хемсворту и Тессе Томпсон в касте предстоящего спин-оффа «Людей в черном». 65-летний актёр, скорее всего, сыграет главу британского отделения агентства, контролирующего пребывание инопланетных пришельцев на Земле.

 

Снимать новых «Людей в чёрном» будет Ф. Гэри Грей, постановщик «Форсажа 8» и «Голоса улиц». К спин-оффу вернутся продюсеры оригинальной франшизы Уолтер Паркерс и Лори МакДональд. Исполнительным продюсером проекта станет Стивен Спилберг. О сюжете проекта также известно, однако оригинальные персонажи Уилла Смита и Томми Ли Джонса точно не появятся в спин-оффе.

 

Серия фильмов «Люди в черном» рассказывает о секретной организации, которая ловит инопланетян, нарушающих порядок на планете Земля. Первая часть фантастического боевика вышла в прокат в 1997 году, вторая в 2002-м. Третья часть серии несколько подзадержалась и вышла только спустя 10 лет.

http://thr.ru/cinema/liam-nison-mozet-snatsa-v-novyh-ludah-v-cernom/?utm_source=tw&utm_medium=social&utm_campaign=65-letniy-aktyor-stanet-glavoy-agentstva&utm_content=19733425

 

 

Lapulia, блог «Лапин House»

Печеньки-медальки

Widowmaker1984, блог «Java для собеседований»

Вопрос 80-89 (модификаторы)

"Можно ли получить доступ к private переменным класса и если да, то каким образом?"
"Модификаторы. Назначение и варианты использования."
"Что такое volatile и transient?"
"Контексты использования модификаторов (класс/поле/метод)."
"Какой из модификаторов более строгий: protected или package-private?"
"Расширение модификаторов при наследовании, переопределение и сокрытие методов. Если у класса-родителя есть метод, объявленный как private, может ли наследник расширить его видимость? А если protected? А сузить видимость?"
"Модификатор abstract и final для классов/методов."
"Имеет ли смысл объявлять метод private final?"
"Какие особенности инициализации final переменных?"
"Что будет, если единственный конструктор класса объявлен как final?"


1. Модификаторы — ключевые слова, которые добавляются при инициализации для изменения значений. Язык Java имеет широкий спектр модификаторов, основные из них:
- модификаторы доступа;
- модификаторы класса, метода, переменной и потока, используемые не для доступа.

скрытый текст2. В Java существуют следующие модификаторы доступа:
- private: члены класса доступны только внутри класса;
- default (package-private) (модификатор, по-умолчанию): члены класса видны внутри пакета (если класс будет так объявлен он будет доступен только внутри пакета);
- protected: члены класса доступны внутри пакета и в наследниках;
- public: члены класс доступны всем;

2.1. Последовательность модификаторов по убыванию уровня закрытости: private, default, protected, public.

2.2. Доступ к полям модификатором доступа private рекомендуется осуществлять через специальные методы с заголовками, начинающимися с get/set.

2.2.1. С помощью Java Reflection можно получить доступ к части кода, к которой мы не должны получать доступ. Например, мы можем получить доступ к закрытым полям класса и менять их значения. Это может быть серьезной угрозой безопасности.

2.3. Во время наследования возможно изменения модификаторов доступа в сторону большей видимости. Так сделано для того, чтобы не нарушался принцип LSP («подкласс не должен требовать от вызывающего кода больше, чем базовый класс, и не должен предоставлять вызывающему коду меньше, чем базовый класс») для наследуемого класса.

2.3.1. Поэтому методы, объявленные как public в суперклассе, также должны быть public во всех подклассах. Методы, объявленные как protected в суперклассе, должны либо быть либо protected, либо public в подклассах; они не могут быть private. Методы, объявленные как private для всех не наследуются, так что нет никакого правила для них.

3. Java предоставляет ряд модификаторов не для доступа, а для реализации многих других функциональных возможностей:
- модификатор static применяется для создания статических методов и переменных класса;
- модификатор final используется для завершения реализации классов, методов и переменных;
- модификатор abstract необходим для создания абстрактных классов и методов;
- модификаторы synchronized и volatile используются в Java для потоков;
- прочие модификаторы (strictfp, transient, native).

3.1. Модификатор synchronized применяется только к методам и их частям. Указывает, что метод может быть доступен только одному потоку одновременно. В Java модификатор synchronized может быть применен с любым из четырех модификаторов уровня доступа.

3.2. Модификатор transient: переменная экземпляра отмеченная как transient указывает виртуальной машине Java (JVM пропустить эту переменную при сериализации содержащего её объекта.

3.2.1. Применяется только для переменных уровня класса (локальные переменные не могут быть объявлены как transient). Transient переменные могут не быть final или static.

3.3. Модификатор volatile используется, чтобы указать JVM, что при обращении к полю не используется кэш (имеется ввиду область памяти в которой JVM может сохранять локальную копию переменной, чтобы уменьшить время обращения к переменной). Для volatile переменной JVM гарантирует синхронизацию для операций чтения/записи, но не гарантирует для операций изменения значения переменной.

3.3.1. Модификатор применим только к переменным экземпляра, которые имеют тип объект или private. Ссылка на объект с модификатором volatile может быть null.

3.3.2. Может использоваться со static переменными. Не используется с final переменными.

3.4. Модификатор strictfp применяется для методов и классов. Обеспечивает выполнение операций над числами типа float и double (с плавающей запятой) по стандарту IEEE 754.

3.5. Модификатор native используется только для методов. Обозначает, что метод написан на другом языке программирования. Классы в Java используют native методы для повышения производительности и доступа к аппаратным средствам Можно предавать и возвращать Java объекты из native методов. Сигнатура метода должна заканчиваться “;”, фигурные скобки вызовут ошибку компиляции.

4.1. Переменная с final может быть инициализирована только один раз. Они не инициализируются по умолчанию, необходимо явно присвоить значение при объявлении или в конструкторе, иначе – ошибка компиляции. Ссылочная переменная, объявленная как final, никогда не может быть назначена для обозначения другого объекта. Однако поля объекта могут быть изменены. Также это справедливо и для массивов, потому что массивы являются объектами: массив может быть изменен, но переменная всегда будет ссылаться на тот же самый массив.

4.1.1. С переменными модификатор final часто используется совместно со static, чтобы сделать переменную класса константой. Подобные переменные должны быть инициализированы во время объявления или в статическом блоке.

4.2. Метод с final не может быть переопределен. Аргументы методов, обозначенные как final, предназначены только для чтения, при попытке изменения будет ошибка компиляции.

4.2.1. Абстрактный класс не может создать экземпляр. Если класс объявлен как abstract, то единственная цель для него быть расширенным через наследование. Класс не может быть одновременно abstract и final, так как класс с модификатором final не может быть расширенным.

4.3. От класса с final нельзя наследоваться. Поэтому все его методы не могут быть переопределены и неявно также становятся финальными.

4.3.1. Абстрактный метод является методом, объявленным без реализации (без тела метода). Методы abstract никогда не могут быть final.

5. "Суперпункт" для разбора частных вопросов.

5.1. "Имеет ли смысл объявлять метод private final?" Модификатор final позволяет заблокировать метод от переопределения в классах наследниках. Однако private методы и так недоступны в классах наследниках, поэтому перепределить такие методы там нельзя и дополнительный модификатор final не окажет никакого влияния. Можно сказать, что private методы и так неявно являются final методами.

5.2. "Что будет, если единственный конструктор класса объявлен как final?" Конструктор не может иметь подобного модификатора.

6. Таблица с возможностью применить модификаторы в том или ином контексте:
http://www.quizful.net/post/features-of-the-application-of-modifiers-in-java

6.1. Классы (включая любые вложенные классы) могут быть default и strictfp. За исключением анонимных они могут быть abstract или final. Вложенные за исключением локальных (включая анонимные) могут иметь модификатор доступа (верхнего уровня — только public). И только вложенные классы могут быть static.

6.2. Методы в общем случае могут использовать все модификаторы за исключением специально предназначенных для переменных transient и volatile. Конструкторы в отличие от методов не может иметь модификаторов abstract, final, native, static или synchronized.

6.3. Переменные в общем случае могут использовать все модификаторы за исключением не имеющих для них смысла abstract, native и strictfp.

6.4. Логический блок может иметь модификаторы default, static и (как часть метода) synchronized.

Эллеонор, блог «Жизненное»

Лицо.

Эти два месяца мое лицо превратилось в п*здец.
Нет, я, конечно, думала, мол: "Вот у меня мордаха милая. А каково себя принимать тем, у кого все лицо фиг знает в чем...".
СУКА.
...
БЛЯТЬ.

Теперь сижу и думаю - хули делать.
С одной стороны, психосоматика. С другой - получила свои же страхи. В третьих, карма. В четвёртых - аллергия. В пятых - ну бляяяяяять.

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

Вчера я съела блин с мясом и у меня чесалось лицо! А сегодня то же было из-за абрикоса! У меня нет аллергии на абрикосы! Мне что, хлебом и водой питаться? Тогда будет достаточно?

И я теперь думаю, как мне из этого выбираться.
С одной стороны, у меня рпп и "просто не есть аллергены" - ну, охуеть, сука, какая пиздатая идея, а я-то не додумалась.
С другой, если я реально перестану кушать все, что у меня может вызвать такую реакцию, то можно начать жевать корочки с хлебом.

С третьей, с большой вероятностью дело не в еде вообще, а в:
а) агрессии к себе;
б) страхе перед миром и людьми.
в) психосоматике в целом.

И нужно разобраться с этим, но для этого надо знать точно, что влияет. А я в своих выводах не уверена. У меня тут нелюбовь к себе, неприятие своего тела, чувство лени и нежелание что-либо делать, страхи, попытки определиться, где лень, а где реально нужно успокоиться и дать себе вольную и так далее. Я даже не знаю, за что хвататься и откуда начинать копать.

Как говорила моя подруга - ты лезешь в частности, забывая "корень" проблемы. Зри в корень и тогда сможешь найти решение.

Alex_Exile, блог «Just give me a reason...»

* * *

Shagel, блог «Sweet Sugar Bones»

* * *

Джулиан, блог «Нэжвилль»

Из цикла "Хозяин степи". Бунт. Часть вторая.

Илпек вышел к Оташу не один, а в сопровождении крепкого мужчины с большим ножом за поясом.
– Здравствуй, великий шоно, – заговорил старейшина.
– Ты знаешь, зачем я здесь, – спешившись, ответил Оташ.
– Мы вынуждены были пойти на крайние меры.
– Чего ты хочешь?
– Отмены дани. И чтобы наши мужчины не шли в армию шоносара.
– А если я откажусь?
– Мальчика придётся убить. И, великий шоно, если ты захочешь забрать его силой, его всё равно убьют. Рядом с ним хороший воин. Он сделает всё быстро.
– Илпек, я никогда не соглашусь на твои условия. Но я дам тебе время одуматься. Я буду ждать до полуночи. Если в полночь ты не выдашь мне Юргена, я прикажу сжечь твоё поселение.
– Великий шоно так не поступит. Ведь тогда погибнут женщины, старики, дети и этот мальчик, Юрген.
– Жду до полуночи, – повторил Оташ, садясь на коня.
Покидая поселение, шоно чувствовал, как его била мелкая дрожь.
– Не одумается он, – проговорил Бальзан.
– Сам знаю, – ответил Оташ.
– Так значит спалить поселение?
– Значит спалить. Что-то имеешь против?
– Нет, – пожал плечами Бальзан. – Все шоно так делали.
читать дальше– Мой отец так не делал.
– Но он подавил бунт.
Оташ промолчал. Вернувшись в лагерь, он увидел дожидавшегося его Рейна.
– Вы ездили на переговоры со старейшиной сиваров, не так ли? – спросил Арчибальд.
– Верно, – ответил шоно.
– И они требуют свободы от шоносара?
– Почти. Илпек не говорил о выходе из-под моего правления, но требовал отмены дани и отказывался отдавать своих мужчин в нашу армию.
– Как вы намерены поступить?
– Я дал ему время передумать. До полуночи.
– Вы считаете, он может передумать?
– Нет. Но мне нужно это время.
– Для чего?
– Чтобы подготовиться. Я сказал Илпеку, что прикажу сжечь его поселение.
– И вы действительно сделаете это?
– По вашему голосу я слышу, что вы это не поддерживаете, – усмехнулся Оташ.

Widowmaker1984, блог «Java для собеседований»

Вопросы 69-78 (класс Object и его методы equals, hashCode, toString)

"Как связан любой пользовательский класс с классом Object?"
"Расскажите про каждый из методов класса Object."
"Что такое метод equals(). Чем он отличается от операции ==."
"Если вы хотите переопределить equals(), какие условия должны удовлетворяться для переопределенного метода?"
"Если equals() переопределен, есть ли какие-либо другие методы, которые следует переопределить?"
"В чем особенность работы методов hashCode и equals? Каким образом реализованы методы hashCode и equals в классе Object? Какие правила и соглашения существуют для реализации этих методов? Когда они применяются?"
"Какой метод возвращает строковое представление объекта?"
"Что будет, если переопределить equals не переопределяя hashCode? Какие могут возникнуть проблемы?"
"Есть ли какие-либо рекомендации о том, какие поля следует использовать при подсчете hashCode?"
"Как вы думаете, будут ли какие-то проблемы, если у объекта, который используется в качестве ключа в hashMap изменится поле, которое участвует в определении hashCode?"


1. В Java есть специальный суперкласс Object и все классы являются его подклассами (это не требуется указывать явно). Поэтому ссылочная переменная класса Object может ссылаться на объект любого другого класса.

1.1. Так как массивы являются тоже классами, то переменная класса Object может ссылаться и на любой массив.

2. У класса есть несколько важных методов:

скрытый текстprotected native Object clone() throws CloneNotSupportedException — создаёт новый объект, не отличающий от клонируемого;
public boolean equals(Object obj) — определяет, равен ли один объект другому;
protected void finalize() throws Throwable — вызывается сборщиком мусора, когда он определил, что ссылок на объект больше нет;
public final native Class getClass() — получает класс объекта во время выполнения;
public native int hashCode() — возвращает хеш-код, связанный с вызывающим объектом;
public final native void notify() — возобновляет выполнение одного потока, который ожидает вызывающего объекта;
public final native void notifyAll() — возобновляет выполнение всех потоков, которые ожидают вызывающего объекта;
public String toString() — возвращает строковое представление объекта;
public final void wait() throws InterruptedException — приводит данный поток в ожидание, пока другой поток не вызовет notify() или notifyAll() методы для этого объекта.;
public final native void wait(long timeout) throws InterruptedException --приводит данный поток в ожидание, пока другой поток не вызовет notify() или notifyAll() для этого метода, или пока не истечет указанный промежуток времени.
public final void wait(long timeout, int nanos) throws InterruptedException — приводит данный поток в ожидание, пока другой поток не вызовет notify() или notifyAll() для этого метода, или пока не истечет указанный промежуток времени.

3. Хеш-код - это целочисленный результат работы метода, которому в качестве входного параметра передан объект. Этот метод реализован таким образом, что для одного и того-же входного объекта, хеш-код всегда будет одинаковым. Следует понимать, что множество возможных хеш-кодов ограничено примитивным типом int, а множество объектов ограничено только нашей фантазией. Отсюда следует утверждение: “Множество объектов мощнее множества хеш-кодов”. Из-за этого ограничения, вполне возможна ситуация, что хеш-коды разных объектов могут совпасть.

3.1. Ситуация, когда у разных объектов одинаковые хеш-коды называется коллизией. Вероятность возникновения коллизии зависит от используемого алгоритма генерации хеш-кода.

3.2. У любого объекта имется хеш-код, определяемый по умолчанию, который вычисляется по адресу памяти, занимаемой объектом.

3.2.1. А, например, для вычисления хеш-кода в классе String применяется следующий алгоритм:

int hash = 0;
for(int i = 0; i < length(); i++)
hash = 31 * hash + charAt(i);

3.3. Выводы:
- Для одного и того-же объекта, хеш-код всегда будет одинаковым.
- Если объекты одинаковые (т.е. одного класса с одинаковым содержимым полей.), то и хеш-коды одинаковые.
- Если хеш-коды равны, то входные объекты не всегда равны (коллизия).
- Если хеш-коды разные, то и объекты гарантированно разные.

4. В Java, каждый вызов оператора new порождает в памяти новый объект, при этом их содержимое может быть одинаково, то есть эквивалентно. Для проверки эквивалентности в классе Object существует метод equals(), который сравнивает содержимое объектов и выводит значение true, если содержимое эквивалентно, и false — если нет.

object1.equals(object2);

4.1. Эквивалентность и хеш-код тесно связанны между собой, поскольку хеш-код вычисляется на основании содержимого объекта (значения полей) и если у двух объектов одного и того же класса содержимое одинаковое, то и хеш-коды по идее должны быть одинаковыми.

4.2. Но на самом деле по умолчанию код метода equals следующий: return (this == obj);
При сравнение объектов, операция “==” вернет true лишь в одном случае — когда ссылки указывают на один объект. В данном случае не учитывается содержимое полей.

4.2.1. При вычислении хэш-кода для объектов класса Object по умолчанию используется Park-Miller RNG алгоритм. В основу работы данного алгоритма положен генератор случайных чисел. Это означает, что при каждом запуске программы у объекта будет разный хэш-код. Получается, что используя реализацию метода hashCode() от класса Object, мы при каждом создании объекта будем получать разные хеш-коды. Мало того, перезапуская программу, мы будем получать абсолютно разные значения, поскольку это просто случайное число.

5. Поэтому, при создании пользовательского класса, принято переопределять методы hashCode() и equals() таким образом, чтобы учитывались поля объекта. Их реализация ложится на плечи разработчика. При переопределении equals() обязательно нужно переопределить метод hashCode(), потому что эквивалентные объекты должны возвращать одинаковые хеш-коды.

5.1. Например, в классе String метод equals переопределяется таким образом, что возвращается true, если содержимое двух сравниваемых строк одинаковое. А в классе-обертке Integer метод equal переопределяется для выполнения численного сравнения.

5.2. Если переопределить equals не переопределяя hashCode объекты данного класса могут неправильно хранится в контейнерах, использующих данные методы при вставке и извлечении объектов, таких как HashMap, HashTable или HashSet.

5.2.1. Для правильной работы этих компонентов Java предлагает следующее правило для переопределения указанных методов: эквивалентным называется отношение, которое является симметричным, транзитивным и рефлексивным.

Рефлексивность: для любого ненулевого x, x.equals(x) вернет true;
Транзитивность: для любого ненулевого x, y и z, если x.equals(y) и y.equals(z) вернет true, тогда и x.equals(z) вернет true;
Симметричность: для любого ненулевого x и y, x.equals(y) должно вернуть true, тогда и только тогда, когда y.equals(x) вернет true.

5.2.1.1. Повторный вызов метода equals() должен возвращать одно и тоже значение до тех пор, пока какое-либо значение свойств объекта не будет изменено. То есть, если два объекта равны в Java, то они будут равны пока их свойства остаются неизменными.

5.2.1.2. Также для любого ненулевого x, x.equals(null) должно вернуть false.

5.2.2. Соглашение между equals и hashCode в Java:
1) Если объекты равны по результатам выполнения метода equals, тогда их hashcode должны быть одинаковыми.
2) Если объекты не равны по результатам выполнения метода equals, тогда их hashcode могут быть как одинаковыми, так и разными. Однако для повышения производительности, лучше, чтобы разные объекты возвращали разные коды.

5.3. Рекомендации как переопределять метод equals в Java (сравнение с объектом obj):
- Проверьте, не указывают ли ссылки на один объект.
- Проверьте объект на null, а также проверьте, чтобы объекты были одного типа. Не делайте проверку с помощью instanceof так как такая проверка будет возвращать true для подклассов. Вместо этого можно использовать getClass();
- Объявите переменную типа, который вы сравниваете, и приведите obj к этому типу. Потом сравнивайте каждый атрибут типа начиная с численных атрибутов (если имеются) потому что численные атрибуты проверяются быстрей. Сравнивайте атрибуты с помощью операторов И и ИЛИ для объединения проверок с другими атрибутами.

5.4. При подсчете хеш-кода необходимо использовать уникальные, лучше примитивные поля, такие как id или uuid. Причем, если эти поля задействованы при вычислении hashCode, их задействовать и при выполнении equals. Более общий совет: выбирать поля, которые с большой долью вероятности будут различаться. Хеш-код должен быть равномерно распределен на области возможных принимаемых значений.

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

6. Метод toString возвращает строковое представление объекта.

6.1. Очень часто при использовании метода toString() для получения описания объекта можно получить набор бессмысленных символов, например, [I@421199e8. На самом деле в них есть смысл, доступный специалистом. Он сразу может сказать, что мы имеем дело с одномерным массивом (одна квадратная скобка), который имеет тип int (символ I). Остальные символы тоже что-то означают, но вам знать это не обязательно.

6.2. По умолчанию метод работает по следующему алгоритму:
getClass().getName() + '@' + Integer.toHexString(hashCode())

6.2.1. Принято переопределять метод, чтобы он выводил результат в читаемом виде.

Лучшее   Правила сайта   Вход   Регистрация   Восстановление пароля

Материалы сайта предназначены для лиц старше 16 лет (16+)