- 기본형: 하나의 값을 여러 변수에서 절대로 공유하지 않는다
- 참조형: 하나의 객체를 참조값을 통해 여러 변수에서 공유할 수 있다
참조형 변수는 참조값을 복사해서 대입하기때문에 여러변수에서 얼마든지 같은 객체를 공유할 수 있다.
객체의 공유는 필요할 때도 있지만 때로는 객체의 공유로 인하여 사이드 이펙트를 만드는 경우도있다.
Ex)예상치 않은 참조로 인해서 기존의 참조변수의 값이 변경되어 사이드이펙트가 발생되는경우
Address addressA = new Address();
Address b = addressA;
위 코드가 객체의 공유를 의미하며 객체의 공유는 아래와 같은 사이드 이펙트를 유발할 수 있다.
public static void main(String[] args) {
Address addressA = new Address();
addressA.setAddress("서울");
System.out.println("addressA = " + addressA);
Address addressB = addressA;
addressB.setAddress("부산");
System.out.println("addressA = " + addressA);
System.out.println("addressB = " + addressB);
}
addressA = Address{address='서울'}
addressA = Address{address='부산'}
addressB = Address{address='부산'}
개발자의 의도는 addressB의 주소만 부산으로 변경하려했지만 객체는 주소를 참조하는 형태를 이루고있기 때문에 addressA의 주소도 부산으로 바뀐 실행결과를 확인할 수 있다.
자바문법상으로 객체가 공유됨을 막을 수 없고, 객체의 공유는 큰 문제를 가져올 수 있기때문에 신중히 해야한다.
결론적으로 보자면, 객체의 공유자체는 문제가 되지 않지만 공유 후에 해당 객체의 값을 변경하였을 때 사이드 이펙트가 발생하게 되는 것이다.
즉 객체의 공유는 허용하더라도 값에 변경을 막기만 하면 자바의 문법만으로도 충분히 객체의 공유에대한 사이드이펙트 가능성을 막을 수 있다.
값에 변경을 막기위해서는 어떻게해야할까?
- 처음 필드의 값을 선언할 때는 생성자만으로 선언
- 해당 객체의 setXXX메서드 선언하지 않음
- 멤버변수에 final키워드 사용
위의 과정을 통하여 불변객체를 생성함으로써 사이드 이펙트문제를 미리 막을 수 있다.
public class ImmutableMain1 {
public static void main(String[] args) {
Address addressA = new Address("서울");
System.out.println("addressA = " + addressA);
Address addressB = addressA;
addressB = new Address("부산");
System.out.println("addressA = " + addressA);
System.out.println("addressB = " + addressB);
}
}
class Address{
private String address;
public Address(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
@Override
public String toString() {
return "Address{" + "address='" + address + '\'' + '}';
}
}
만약 불변객체를 설계할 때 값을 변경하는 메서드가 필요할 수 있는데 이 경우에는 기존 객체의 값은 불변하도록 유지하고, 메서드를 통해 새로운 값을 생성해 리턴하도록 하면 된다.
불변클래스의 용도
일반적인 클래스는 대부분 값을 변경할 수 있도록 가변 클래스로 만들어진다.
회원 클래스의 같은 경우에도 값을 변경할 수 있도록 가변클래스로 설계 된다.
불변 클래스는 값을 변경하면 안되는 특별한 경우에 만들어서 사용된다.
이 때 메서드의 이름은 setXXX가 아닌 withXXX로 설계한다.
불변으로 설계하는 여러 이유
- 캐시 안정성
- 멀티 쓰레드 안정성
- 엔티티의 값 타입
'Language > Java' 카테고리의 다른 글
해시 알고리즘 (0) | 2024.06.29 |
---|---|
[JAVA - 자료구조] HashSet (0) | 2024.06.29 |
[JAVA] 래퍼 클래스 (0) | 2024.06.24 |
[Java] Enum타입 (1) | 2024.06.18 |
[Java] - Generic (1) | 2024.06.15 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!