Подскажите, пожалуйста, в чем заключается моя ошибка? Запретила клонирование класса B путем выкидывания CloneNotSupportedException, но валидатор все равно ругается..Класс С клонируется успешно. Что не так?
Jola
40 уровень
Вопрос по клонированию
Решен
Комментарии (6)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Сергеев ВикторMaster
2 декабря 2017, 23:47
Вы смотрели реализуцию clone у Object? Я не помню какой он там, но в А вы делегируете клонирование ему, а в С делаете руками.
Так же из условий "Не забудь о методах equals и hashCode!"
0
Jola
3 декабря 2017, 11:37
обновила код, в A и С клонирую ручками, equals и hashcode переопределила, на всякий случай добавила проверки на null, получается следующее:
1. c != c.clone() // = true
2. c.clone().getClass() == c.getClass() // =true
3. c.clone().equals(c) // =false - вот этого не могу понять, хотя в доках
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#clone()
указано:
" x.clone().equals(x)
will be true, this is not an absolute requirement. "
Хеш-коды разные.
Разреши клонировать класс А - переопределяем clone(),
Запрети клонировать класс B - бросаем exception
Разреши клонировать класс C - переопределяем clone()
Валидатор все равно указывает на метод clone() класса B.
Буду благодарна, если кто скажет, куда копать...
+1
Сергеев ВикторMaster
3 декабря 2017, 15:25полезный
Хеш код Object это адресс объекта в памяти (но это не точно), т.е. на 2 одинаковых объекта вы получаете разные хешкоды - это не правильно.
Одинаковые объекты должны иметь одинаковый хешкод. Разные объекты имеют разный хешкод, но бывают случаи, когда разные объекты имеют одинаковый хешкод (коллизия).
+1
Jola
4 декабря 2017, 00:03
убрала переопределение equals() и hashCode(), поставила проверку на null на параметр name в методе класса С и к моему большому удивлению валидатор схавал, но остался осадок непонимания...
При клонировании меня тупило, так как мои мысли были посвящены тому, что при создании объекта выделяется память под объект, кто привело меня к мысли что хеш-коды оригинала и клона должны быть разные, но здесь же клонирование. После Вашего комментария вспомнила, что при клонировании копируются ссылки на объекты, в данном случае значения полей, которые равны, то есть получается клон и оригинал ссылаются на одинаковые области памяти? То есть при клонировании должны выполняться следующие условия (или не всегда?):
1. c != c.clone() // = true
2. c.clone().getClass() == c.getClass() // =true
3. c.clone().equals(c) // =true и соответственно равны хеш-коды
Поправьте меня, пожалуйста, если я неправильно Вас поняла.
0
Сергеев ВикторMaster
4 декабря 2017, 01:31полезный
нет при клонировани создается новый идентичный объект. Он находится в другом месте в памяти ( там же в куче, но другой объект ). Соответственно имеет другую ссылку.
Для этого и надо переопределять equals и hashCode, чтобы сравнивать объекты по полям, а не по ссылкам.
Пример:
С завода вышло 2 идентичные машины и их купили 2 разных человека. У них 2 разных владельца (разные ссылки), но машины все так же идентичные.
Хешкод - дает цифровое обозначение объекта.
Equals - сравнивает объект полностью.
В основном это используется в хеш структурах (HashSet, HashMap). Чтобы долго не искать, объект сначала ищется по хешкоду. Когда найден - сравнивается через equals.
И да, чтобы получить копи ссылки на объект достаточно сделать так:
+4
Jola
4 декабря 2017, 09:01
Да уж..Я сама себя заплутала, но все равно спасибо за корректное объяснение.
0