JAVA/JPA

(JPA) 값 타입과 불변객체

ri5 2021. 7. 6. 19:24

값 타입


값 타입은 복잡한 객체 세상을 조금이라도 단순화하려고 만든 개념이다. 따라서 값 타입은 단순하고 안전하게 다룰 수 있어야 한다.

 

공유 참조

• 임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 위험함

• 부작용(side effect) 발생

Address address = new Address("city","street","10000");
Member member = new Member();
member.setName("member1");
member.setHomeAddress(address);
em.persist(member);

Member member2 = new Member();
member2.setName("member2");
member2.setHomeAddress(address);
em.persist(member2);

member.getHomeAddres().setCity("newCity")

※ 둘다 같은 값을 공유하고 있기 때문에 member2의 값도 바뀐다.

 

객체 타입의 한계

• 항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용 을 피할 수 있다.

• 문제는 임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입이다.

• 자바 기본 타입에 값을 대입하면 값을 복사한다.

• 객체 타입은 참조 값을 직접 대입하는 것을 막을 방법이 없다.

객체의 공유 참조는 피할 수 없다.

 

기본 타입

int a = 10; 
int b = a;//기본 타입은 값을 복사
b = 4;
// a = 10 b = 4

객체 타입

ddress a = new Address(“Old”); 
Address b = a; //객체 타입은 참조를 전달
b.setCity(“New”)
// side effect 발생!!
// a.getCity() = "New"
// b.getCity() = "New"

 

불변 객체

 


• 객체 타입을 수정할 수 없게 만들면 부작용을 원천 차단

• 값 타입은 불변 객체(immutable object)로 설계해야함

• 불변 객체: 생성 시점 이후 절대 값을 변경할 수 없는 객체

• 생성자로만 값을 설정하고 수정자(Setter)를 만들지 않으면 됨

• 참고: Integer, String은 자바가 제공하는 대표적인 불변 객체

 

※ side effect는 컴파일러 단계에서 추적이 안되기 때문에 찾기 매우 어렵다.