Обеспечение одинакового поведения разных конструкторов в Java
На прошлой неделе я был на собеседовании, и одним из вопросов в тесте по программированию было: "Как вы можете гарантировать, что разные конструкторы в классе ведут себя одинаково в Java?". Я не был и до сих пор не уверен, что означает "иметь такое же поведение". Ответ, который я дал, был:
(new MyObject(...)).equals(new MyObject(...));
(new MyObject(...)).hashCode == (new MyObject(...)).hashCode();
Здесь в каждой строке первый MyObject(...) ссылается на один конструктор, а второй - на другой.
Как вы думаете, вопросы на самом деле задавали?
4 ответа
Я не считаю ваш ответ правильным. Вы только доказываете, что два объекта равны (Кстати, если объекты равны, они должны иметь одинаковые hashCode()
Второе сравнение является излишним).
Я думаю, что правильное решение состоит в том, чтобы иметь один первичный конструктор и делегировать ему все остальные конструкторы, вызывая this(...)
, Если все неосновные конструкторы настолько коротки, насколько это возможно, скорее всего, они будут вести себя одинаково, поскольку все они делегируют один и тот же код.
И конечно: юнит-тестирование могло бы быть и правильным ответом.
Я думаю, что это было связано с использованием this()
а также super()
,
Это зависит от того, как вы определяете equals и hashcode
например (худший!) рассмотрим следующую реализацию equals()
return true;
и hashcode()
return 1;
теперь даже не важно, в каком состоянии находится объект!
В случае, если классы, на которые вы ссылаетесь, не переопределяют данные методы, все равно equals будут false, поскольку они представляют собой два разных объекта (их детали выделения памяти различны). Хеш-код тоже не будет работать.
Я думаю, что вы можете написать кусок кода, который пересекает классы, используя отражение, и проверяет для каждого поля, что оно имеет одинаковое значение. В конце эти два экземпляра отличаются только полями (не методами, так как они установлены во время компиляции).
Удачи на следующем собеседовании.