하나의 값을 여러 변수에서 절대 공유하지 않음
하나의 객체를 참조값을 통해 여러 변수에서 공유 가능
Member m1 = new Member();
m1.name = "김진슝";
Member m2 = m1;
m2.name = "홍길동";
System.out.println(m1.name); // 홍길동
System.out.println(m2.name); // 홍길동
사이드 이펙트란?
참조형 객체를 여러 곳에서 공유할 때, 한 곳의 변경이 다른 곳에도 영향을 주는 현상
Member m1 = new Member();
m1.name = "김진슝";
Member m2 = m1;
m2.name = "홍길동";
System.out.println(m1.name); // 홍길동
System.out.println(m2.name); // 홍길동
위 코드를 봤을 때 m2의 이름을 바꿨는데 m1 까지 바뀌었다.
실제로는 둘 다 같은 객체를 가리키기 때문에 (같은 인스턴스 참조) 객체 하나가 변경된 것이다.
해결 방안은?
처음부터 다른 인스턴스를 참조하면 된다.
Member m1 = new Member("김진슝");
Member m2 = new Member("함지성");
하지만 참조값을 공유한다고 해서 컴파일상에서 오류가 뜨는것이 아니기에 막을 방법이 없다.
-> 이때 불변 객체를 사용 :: 객체의 값을 바꿀 수 없게 만들면 된다.
객체의 상태(객체 내부 값 : 필드, 멤버 변수)가 변하지 않는 객체를 불변 객체라고 부른다.
public class Member {
private final String name;
public Member() {
this.name = name;
}
public String getName() {
return value
}
}
객체 내부의 값을 final로 선언하고 setter를 제거해, 생성자를 통해서 값을 설정하고 이후 변경이 불가능하게 했다.
Member m1 = new Member("김진슝");
Member m2 = m1;
m2 = new Member("홍길동");
System.out.println(m1.name); // 김진슝
System.out.println(m2.name); // 홍길동
불변 객체를 사용하지만 값을 변경해야 되는 경우가 있다면?
public class Member {
private final int age;
public Member(int age) {
this.age = age;
}
public Member add(int addAge) {
int res = age + addAge;
return new Member(res);
}
public int getAge() {
return age;
}
}
Member m1 = new Member(3);
Member m2 = m1.add(10);
System.out.println(m1.getAge()); // 3
System.out.println(m2.getAge()); // 13
자바에서 가장 많이 사용되는 String 클래스는 불변 객체이다.
또한 자바에서 기본으로 제공하는 Integer, LocalDate 등 수 많은 클래스가 불변 객체로 설계되어 있다.
모든 클래스가 불변은 아니다
가변 클래스가 더 일반적이고, 불변 클래스는 값을 변경하면 안되는 경우에 만들어서 사용해야 한다.
캐시 안정성, 멀티 쓰레드 안정성, 엔티티 값 타입 등 수 많은 이유로 클래스를 불변으로 설계하곤 한다.