Overview
public void updateMbtiScore(BookMBTI bookMBTI, LikeMbti like) {
int multiplier = (like.getLikeStatus() == LikeStatus.DISLIKE) ? 2 : 1;
this.eScore += multiplier * bookMBTI.getEScore();
this.iScore += multiplier * bookMBTI.getIScore();
this.sScore += multiplier * bookMBTI.getSScore();
this.nScore += multiplier * bookMBTI.getNScore();
this.tScore += multiplier * bookMBTI.getTScore();
this.fScore += multiplier * bookMBTI.getFScore();
this.jScore += multiplier * bookMBTI.getJScore();
this.pScore += multiplier * bookMBTI.getPScore();
}
like.getLikeStatus() == LikeStatus.DISLIKE 부분은 enum끼리의 비교입니다.
이렇게 enum을 비교하는 로직을 짜면서 equals를 쓰면 좋을지 == 를 쓰면 좋을지에 대한 의문이 생겼습니다.
그래서 이번 글에서는 Enum의 비교에 대해 정리하려 합니다.
Enum 값을 비교하기(== vs equals)
Java에서 Enum 은 클래스 인스턴스가 JVM 내에 하나만 존재하도록 100% 보장되는 싱글톤 객체입니다.(JLS, 8.9 Enum Types) 그렇다면 Enum 비교 시 equals 메서드 대신 간단히 == 비교를 사용하면 어떨까요?
간단하게 테스트 코드를 통해서 확인해 보겠습니다.
public class EnumTest {
@Test
void enumTest() {
Mbti mbti = Mbti.ISFJ;
assertThat(mbti == Mbti.ISFJ).isTrue();
assertThat(mbti.equals(Mbti.ISFJ)).isTrue();
assertThat(Mbti.ISFJ == mbti).isTrue();
assertThat(Mbti.ISFJ.equals(mbti)).isTrue();
}
public enum Mbti {
ISTP,
ISFJ
}
}
테스트를 수행해 보면 모두 통과하는 것을 확인할 수 있는데, 이는 equals 메서드를 확인해 보면 알 수 있습니다.
아래 그림에서와 같이 equals 메서드도 결국 == 연산자를 통해서 비교하고 있는 것을 확인할 수 있습니다.
1. == 비교는 NullPointerException을 발생시키지 않습니다.
public class EnumTest {
@Test
void enumTest() {
Mbti mbti = null;
System.out.println(mbti == Mbti.ISFJ);
System.out.println(mbti.equals(Mbti.ISFJ)); // NPE 발생
System.out.println(Mbti.ISFJ == mbti);
System.out.println(Mbti.ISFJ.equals(mbti));
}
public enum Mbti {
ISTP,
ISFJ
}
}
== 비교는 NPE(NullPointerException)을 발생시키지 않습니다.
eqauls 메서드를 사용하여 비교하면 Runtime(런타임)에 NPE가 발생할 수 있습니다.
(But, equals 메서드에서도 Enum을 먼저 앞에 두고 비교하면 NPE에서 벗어날 수 있습니다.)
위에 설명에서와 같이 NPE를 방지하는 것뿐만 아니라 상수값, Enum과 같은 변하지 않는 값들을 앞에 작성해서 비교하는 것이 좋습니다.
2. == 비교는 컴파일 타임에 타입 호환성 검사를 지원합니다.
위의 그림에서 확인하실 수 있듯이, == 비교를 사용하면 실수로 잘못된 타입 비교를 작성하여도 컴파일 과정에서 확인이 되지만 equals 메서드를 사용하게 되면 그대로 컴파일이 되어 버립니다. 즉 == 비교를 사용하면 프로그래머가 실수로 잘못된 타입 비교를 작성해도 컴파일 타임에 검사 되지만 equals 메서드를 사용하면 그대로 컴파일이 되어 버립니다.
마무리
== 비교가 코드도 간결해지고 직관적이기 때문에 정답이라고 생각했습니다.
하지만 반대의 생각을 가지신 분들도 많은 주제인 것 같습니다.
(참고: stackoverflow/comparing-java-enum-members-or-equals)
그래서 이 문제는 정답이 딱 정해져 있는 문제는 아니라고 생각하지만 컴파일 단계에서 실수를 확인할 수 있는 == 비교가 조금 더 유용하지 않을까라는 생각을 가지게 되었습니다.
참고
'프로젝트 > Kidsping' 카테고리의 다른 글
개발 기록 - 선착순 응모 시스템 이슈 및 해결 과정 (0) | 2024.10.30 |
---|---|
트러블 슈팅 - AWS 프리티어 EC2 인스턴스 메모리 부족 현상 해결하기 (0) | 2024.10.25 |
개발 기록 - N + 1 문제 fetch join, Batch Size로 해결 (0) | 2024.10.24 |
개발 기록 - 자녀 성향 진단 로직 구현 및 리팩터링 (0) | 2024.10.22 |
개발 기록 - @RequestBody DTO에 값이 안들어오는 이유 (Jackson, Lombok) (0) | 2024.10.22 |