Ответ
Spring (и Java в целом) различает такие объекты по их идентичности (identity), а не только по логическому равенству.
1. В контексте бинов Spring:
- Синглтоны (по умолчанию): Контейнер всегда возвращает один и тот же экземпляр (один объект в памяти). Сравнение через
==будетtrue. - Бины с областью видимости prototype: При каждом запросе (
getBean()или инъекции) создается новый экземпляр. Даже если эти экземпляры логически равны (equals()возвращаетtrue), они являются разными объектами в памяти (==вернетfalse).
@Component
@Scope("prototype")
public class PrototypeBean {
private String data;
// equals() и hashCode() переопределены для сравнения по полю 'data'
}
// В коде:
PrototypeBean beanA = context.getBean(PrototypeBean.class);
PrototypeBean beanB = context.getBean(PrototypeBean.class);
beanA.setData("test");
beanB.setData("test");
System.out.println(beanA.equals(beanB)); // true (логическое равенство)
System.out.println(beanA == beanB); // false (разные объекты в памяти)
2. В общем контексте Java:
==сравнивает ссылки (адреса в памяти).equals()сравнивает логическое содержимое объектов (если метод переопределен).- Коллекции, такие как
HashSetилиHashMap, используютhashCode()иequals()для определения уникальности элементов. Два объекта сequals() == trueбудут считаться одним ключом вHashMap, даже если это разные экземпляры.
Best practice: Всегда согласованно переопределяйте equals() и hashCode() для классов, экземпляры которых будут храниться в hash-коллекциях или сравниваться по значению.