JPA/값 타입

값 타입의 비교

CodeMania 2021. 8. 31. 00:22

값 타입이 무엇인지 잘 모르신다면? 아래 글을 참고해주세요!!!

2021.08.28 - [JPA/값 타입] - 값 타입

 

값 타입

JPA 데이터 타입의 분류 JPA에는 크게 엔티티 타입과 값 타입이라는 두 개의 타입이 존재한다. 무엇인지 알아보자! 1. 엔티티타입 @Entity로 정의하는 클래스는 엔티티 타입으로 데이터가 변해도 식

code-mania.tistory.com

값 타입 부분에서는 객체의 기본적인 내용들이 어느정도 다뤄지고 있다.
사실 제목은 값 타입의 비교이지만, 객체의 비교를 아주 가볍게 다뤄볼 것이다.
또한 값 타입 중 기본(primitive) 타입을 제외한 나머지 타입들에 해당되는 내용이다!
(음, 강의 듣고 정말 가볍게 정리했으니 객체의 비교를 이미 아시는 분은 통과해주세요 ㅠㅠ)

github 전체코드 주소(branch: equals)


값 타입의 비교

값 타입을 비교할 때 인스턴스의 참조값이 달라도 내부의 값이 같다면 같은 것으로 봐야 한다.

값 타입에서 기본(primitive) 타입을 제외하면 나머지 타입들은 클래스이기때문에
==을 사용하여 비교하면 내부 값이 같다고 해도 인스턴스의 참조값이 다르다면 false가 반환된다.

따라서 equals 메서드를 통해 비교해야 한다.
equals는 기본적으로 인스턴스의 참조값을 비교(== 비교)를 하기때문에 Overriding해서 사용해야 한다.

별 거 없지만 코드를 통해서 살펴보겠다!

 

Period.java

package hellojpa;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.Embeddable;
import java.time.LocalDateTime;
import java.util.Objects;

@Getter
@Setter
@Embeddable
public class Period {
    private LocalDateTime admissionDate;
    private LocalDateTime graduationDate;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Period period = (Period) o;
        return Objects.equals(admissionDate, period.admissionDate) && Objects.equals(graduationDate, period.graduationDate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(admissionDate, graduationDate);
    }
}

 

equals 메서드와 hashCode 메서드를 재정의했다. 둘 다 intellij를 통해 자동완성했다.
(intellij에서는 사용할 필드만 고르면 그 필드들을 통해서 equals와 hashCode를 만들어준다.

hashCode와 equals를 쌍으로 같이 만들어주는데, 그 이유는 이 두 메서드와 컬렉션의 밀접한 관계때문이다.
컬렉션에서는 a.equals(b) && a.hashCode() == b.hashCode()가 true이면 같은 객체로 취급한다.

그래서 intellij는 equals를 재정의하려고 하면 컬렉션에서의 사용까지 고려해 hashCode도 재정의해준다.
무슨 말인지 잘 모르겠다면 hashCode()만 검색해도 내용이 많이 나온다. 직접 검색해보자!)

 

equals 메서드를 살펴보면, 먼저 == 비교 후 같을 경우 true를 반환하고,
넘어온 객체가 null이거나 넘어온 객체의 클래스와 자신의 클래스를 비교해 같지 않으면 false를 반환한다.
(음, 넘어온 객체가 null이어도 false를 반환하는 건
equals 메서드를 호출한 순간 자신(this)은 null일 수 없다. 따라서 false를 반환해버려도 된다!)

그 후 넘어온 객체를 형변환 후 모든 필드를 Objects.equals()를 통해 비교해준다.

 

hashCode는 Objects.hash()에 모든 필드를 대입한 결과를 반환하도록 만들었다.

JpaMain.java

package hellojpa;

import java.time.LocalDateTime;

public class JpaMain {

    public static void main(String[] args) {
        LocalDateTime admissionDate = LocalDateTime.now();

        Period period1 = new Period();
        period1.setAdmissionDate(admissionDate);
        period1.setGraduationDate(null);

        Period period2 = new Period();
        period2.setAdmissionDate(admissionDate);
        period2.setGraduationDate(null);

        System.out.println("(period1 == period2) = " + (period1 == period2)); //false
        System.out.println("(period1.equals(period2)) = " + (period1.equals(period2))); //true
    }
}

 

period1 == period2의 결과값은 false가 반환되고,
period1.equals(period2)의 결과값은 true가 반환된다.

만약에 equals 함수를 제거하고 코드를 실행시키면 == 비교와 equals 비교 모두 false를 반환한다.
(참고로 Period class에 @Data 어노테이션을 사용하면 equals 메서드 제거 후에도 true가 반환되니 주의하자!)

 

어려운 부분은 없었다. 그냥 아는 내용 한 번 더 봤다고 생각하자!
그리고 맨 처음에도 말했듯, 오늘 배운 내용들은
값 타입 중 기본(primitive) 타입은 제외되고 나머지 타입들에 해당되는 내용이다.

 

참고강의: 배달의 민족 개발팀장 김영한 강사님의 JPA 강의