При использовании интерфейса как дженерика для List, столкнулся с тем, что изменение объекта B приводит к изменениям объекта А
Преамбула такова, хотел наполнить List 2-мя объектами с одним общим предком-интерфейсом (HasSocr)
Но, мне необходимо было сделать проверку на то, что после изменения объекты не остались равны и стали разными, дабы их можно было отдать в транзакцию на update.
private List<HasSocr> getFilledResultList(List<HasSocr> entityList) {
List<HasSocr> resultList = new ArrayList<>();
for (int i = 0; i < entityList.size(); i++) {
HasSocr oldHasSocr = entityList.get(i);
HasSocr newHasSocr = entityList.get(i);
if (oldHasSocr != null && newHasSocr != null) {
if (newHasSocr.getSocr() != null) {
newHasSocr.setSocrName(newHasSocr.getSocr().getFullName());
newHasSocr.setSocrShort(newHasSocr.getSocr().getScName());
if (!hasSocrEquals(oldHasSocr, newHasSocr)) {
resultList.add(entityList.get(i));
}
}
}
}
return resultList;
}
private boolean hasSocrEquals(HasSocr oldHasSocr, HasSocr newHasSocr) {
return oldHasSocr != null
&& newHasSocr != null
&& oldHasSocr.getSocrName().equals(newHasSocr.getSocrName())
&& oldHasSocr.getSocrShort().equals(newHasSocr.getSocrShort())
&& newHasSocr.getSocr().getScName().equals(oldHasSocr.getSocr().getScName())
&& newHasSocr.getSocr().getFullName().equals(oldHasSocr.getSocr().getFullName());
}
Но обнаружил что объекты при использовании
hasSocrEquals(oldHasSocr, newHasSocr)
всегда являются одинаковыми, и больше всего меня повергло в шок то, что если пройти по строчно в дебаге, то видно что:
newHasSocr.setSocrName(newHasSocr.getSocr().getFullName());
Меняет значение поля SocrName и для объекта oldHasSocr. Отсюда и вопрос - почему?
Ответы (1 шт):
В коде
HasSocr oldHasSocr = entityList.get(i);
HasSocr newHasSocr = entityList.get(i);
обе ссылки oldHasSocr и newHasSocr относятся к одному и тому же i-ому элементу списка entityList, то есть к одному и тому же объекту, следовательно фактически у вас выполнится тождественное равенство oldHasSocr == newHasSocr.
Соответственно, это и есть причина того, что все изменения в объекте, на который ссылается newHasSocr отразятся и по ссылке oldHasSocr -- объект один и тот же.
Как минимум вам следовало обращаться к объектам по разным индексам типа i и i + 1, при условии что список заполнен корректно разными экземплярами.