-
@EqualsAndHashCode, equals, hashCodeSpring 2023. 1. 18. 22:23
equals 와 hashCode란?
equals 와 hashCode는 Object 클래스에 정의되어 있다. Object 클래스의 자식인 Java의 모든 객체는 Object 클래스에 정의된 equals 와 hashCode 함수를 상속받는다.
equals()
boolean equals(Object obj)로 정의된 equals 메소드는 2개의 객체가 동일한지 검사하기 위해 사용된다.
equals는 2개의 객체가 참조하는 것이 동일한지를 확인하는 것이며, 동일성(identity)을 비교하는 것이다. 즉, 2개의 객체가 가리키는 곳이 동일한 메모리 주소일 경우에 동일한 객체가 된다.
public boolean equals(Object obj) { return (this == obj); }
동일한 객체일지라도 서로 다른 메모리 상에 존재하면 equals는 false를 반환한다.
하지만 같은 값을 지니므로 같은 객체로 인식되어야 할 경우가 있다. 이러한 동등성(Equality)를 위해 값으로 객체를 비교하도록 equals 메소드를 오버라이딩 해주어야 한다.
예) String 클래스의 equals 메소드
String 클래스에서는 equals 메소드를 오버라이드 하여 객체가 같은 값을 갖는지 동등성(Equality)을 비교하도록 하였다.
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
hashCode()
hashCode 메소드는 실행 중에(Runtime) 객체의 유일한 integer 값을 반환한다. Object 클래스에서는 heap에 저장된 객체의 메모리 주소를 반환하도록 되어있다. 일반적으로 각 객체의 주소값을 변환하여 생성한 객체의 고유한 정수값이다.
hashCode는 HashTable과 같은 자료구조를 사용할 때 데이터가 저장되는 위치를 결정하기 위해 사용된다.
equals 와 hashCode
동일한 객체는 동일한 메모리 주소를 갖는다는 것을 의미하므로, 동일한 객체는 동일한 해시코드를 반환해야 한다.즉, equals() 메소드를 오버라이드 한다면, hashCode() 메소드도 함께 오버라이드 해주어야 한다.
- 두 객체가 equals()에 의해 동일하다면, 두 객체의 hashCode()값도 일치해야 한다.
- 두 객체가 equals()에 의해 동일하지 않다면, 두 객체의 hashCode() 값은 일치하지 않아도 된다.하지만 다른 객체에 대해 동일한 hashCode를 생성한다면 hashTable을 생성하는 데에 불이익을 받을 수 있음을 인지해야 한다.
@EqualsAndHashCode
@EqualsAndHashCode 은 equals, hashCode를 자동으로 생성해주는 어노테이션이다.
클래스에 있는 모든 필드들에 대한 비교를 수행한다.
Include, Exclude
Equals 와 HashCode 생성을 위한 비교 수행에서 어떤 필드를 사용하고, 제외할지 수정할 수 있다.
EqualsAndHashCode (of="id")
연관 관계가 복잡해질 때, @EqualsAndHashCode에서 서로 다른 연관 관계를 순환 참조 하느라 무한 루프가 발생하고, 결국 stack overflow가 발생할 수 있기 때문에 주로 id 값만 비교하도록 사용한다.
CallSuper
callSuper 속성을 통해 부모 클래스의 필드까지 감안할지 안 할지에 대해서 설정할 수 있다.
callSuper = true 로 설정하면, 부모 클래스 필드 값들도 동일한지 체크하며, callSuper = false로 설정(기본값) 하면 자신 클래스의 필드 값만 고려한다.
참고
'Spring' 카테고리의 다른 글
Spring의 @EventListener (0) 2023.01.30 Entity와 DTO 분리하기 (0) 2023.01.25 Setter 사용을 지양해야 하는 이유 (0) 2023.01.19 PasswordEncoder, BcryptPasswordEncoder (0) 2023.01.19 Spring Security : Web Ignore (0) 2023.01.19