728x90
지난 글에서는 값 타입에 대해 알아보았다.
https://un-lazy-midnight.tistory.com/102
값 타입은 복잡한 객체 세상을 조금이라도 단순화하려고 만든 개념이다.
따라서 값 타입은 단순하고 안전하게 다룰 수 있어야 한다.
값 타입 공유 참조
- 임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 위험하다.
- 사이드 이펙트 발생
예)
위와 같이 한쪽 회원의 city 값만 변경하고 싶어도 두 회원이 공유하고 있기 때문에 둘다 NewCity로 변경된다.
이런 경우에는 값 타입 복사를 사용해야 한다.
값 타입 복사
- 값 타입의 실제 인스턴스인 값을 공유하는 것은 위험하다.(위에 예제 처럼)
- 그 대신 값(인스턴스)를 복사해서 사용해야 한다.
객체 타입의 한계
- 항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 사이드 이펙트를 피할 수 있다.
- 임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입이다.
- 자바 기본 타입에 값을 대입하면 값을 복사하지만 객체 타입은 참조 값을 직접 대입하는 것을 막을 방법이 없다.
- 즉, 객체의 공유 참조는 피할 수 없다.
예) 기본 타입
int a = 10;
int b=a;//기본 타입은 값을 복사
b = 4;
객체 타입
Address a = new Address(“Old”);
Address b = a; //객체 타입은 참조를 전달
b. setCity(“New”);
불변 객체
- 생성 시점 이후 절대 값을 변경할 수 없는 객체
- 객체 타입을 수정할 수 없게 만들면 사이드 이펙트를 원천 차단할 수 있다.
- 값 타입은 불변 객체(immutable object)로 설계해야 한다.
- 생성자로만 값을 설정하고 수정자(Setter)를 만들지 않으면 된다.
- 참고: Integer, String은 자바가 제공하는 대표적인 불변 객체이다.
불변이라는 작은 제약으로 부작용이라는 큰 재앙을 막을 수 있다.
값 타입의 비교
값 타입은 인스턴스가 달라도 그 안에 값이 같으면 같은 것으로 봐야 한다.
- 동일성 비교: 인스턴스의 참조 값을 비교, == 사용
- 동등성 비교: 인스턴스의 값을 비교, equals()를 사용
즉, 값 타입은 a.equals(b)를 사용해서 동등성 비교를 해야한다.
값 타입의 equals() 메소드를 적절하게 재정의(주로 모든 필드 사용)
*참고: Use getters during code generation을 체크할 것!
이걸 체크하지 않으면 필드에 직접 접근하기 때문, 프록시를 고려해서 getter로 접근하는게 좋다.
//equals를 재정의 한다.
//자동으로 해주는 걸 사용하자.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Address address = (Address) o;
return Objects.equals(city, address.city) && Objects.equals(street, address.street) && Objects.equals(zipcode, address.zipcode);
}
@Override
public int hashCode() {
return Objects.hash(city, street, zipcode);
}
예)
== 비교를 하면 참조 값을 비교하므로 false
equals()로 비교를 하면 값을 비교하므로 true
int a = 10;
int b = 10;
// a == b 는 true
Address a = new Address("서울시");
Address b = new Address("서울시");
// a == b 는 false
// 자바의 경우 참조값을 비교하는데 참조값이 다르기 때문이다.
// a.equals(b) = true
728x90
'💻dev > 🌱Java+Spring' 카테고리의 다른 글
JPA | 예제로 알아보는 영속성 전이 (예제 - 5) (0) | 2023.05.02 |
---|---|
JPA | 값 타입 컬렉션이란? (저장, 조회, 수정 예제 및 주의사항) (0) | 2023.05.02 |
JPA | 기본값 타입과 임베디드 타입이란? (0) | 2023.05.01 |
JPA | 영속성 전이(CASCADE)와 고아 객체란? (0) | 2023.05.01 |
JPA | 즉시 로딩(FetchType.EAGER)과 지연 로딩(FetchType.LAZY) (0) | 2023.05.01 |