final 과 불변의 객체

Thomas·2023년 5월 24일
3
post-thumbnail

어제 전 팀원분이 final을 대해서 처음 알으셨다고 하셔서 final의 대충 설명과 함께 테코톡에서 final 발표를 재밌게 들은게 있어서 영상 추천을 해준 김에 오랜만에 다시 영상을 보게 되었다
링크: https://www.youtube.com/watch?v=ej-bnXlHk-E
발표해주신 시카님한테 감사의 말씀을 드리겠습니다

final

final은 단 한 번만 할당 가능하다
그래서 재할당하려고 하면 컴파일 오류가 발생해서 즉각적으로 확인 가능하다는 장점이 있다.

그렇다고 굳이 써야하나??
-> 사람은 항상 실수를 하기 떄문에 그 실수를 예방을 하기 위해서 쓰는 습관을 들이는게 좋다

final을 사용하면 값에 대한 검증이 되어 있어서
오로지 로직 구현에 집중을 할 수 있다.
그리고 예상치 못한 변수에 대비해서 심리적 안정감도 얻을 수 있다.

public int addFromTo(final int a, final int b) {
  int sum = 0;
  for(int i = a; i <= b; i++) {
      sum += i;
  }
return sum;
}

a= 3 b =5
3 + 4 + 5 = 12

public int addFromTo(final int a, final int b) {
	return addFromOneTo(b) - addFromOneTo(a-1);
}

private int addFromOneTo(final int n) {
	return (n * (n + 1)) / 2;
}

a= 3 b =5
(5 (5+1)) / 2 = 15 for b
(2
(2+1)) /2 = 3for a-1
15 - 3 = 12

예제1,2 모두 같은 값을 출력 한다는걸 알수 있다.

따라서 불변을 유지한채로 코드를 짜다보면 객체지향적인 코드를 짜게 디렉션을 갈수있다.
그리고 버그 발생 가능성이 줄어들고 찾는 시점이 빨라진다
그래서 코드 품질이 높아져 변화에 좀 더 빠르게 대응 할 수 있다.

불변 객체

한 번 생성되면 상태를 수정할 수 없는 객체 -> 생성이 된 불변 객체는 신뢰할 수 있다.

상속도 안 된다!!

불변 객체 장점

스레드 동기화 문제 방지

여러 쓰레드가 동시에 실행 되면
즉, 아래의 코드가 두개가 있고 동시에 실행이 된다고 생각을 해보자

public class ATM1 {
	private int money;
    
    public ATM1(final int money) {
    	this.money = money;
    }
    
    public void add(final int money) {
    int addResult = this.money + money;
    this.money = addResult;
}
public class ATM2 {
	private int money;
    
    public ATM2(final int money) {
    	this.money = money;
    }
    
    public void add(final int money) {
    int addResult = this.money + money;
    this.money = addResult;
}

ATM1은 5000원 ATM2는 1000원 넣었으면
최종 결과는 ATM2에 있는 1000원 나오므로 총 6000원을 넣었는데 1000원이 나오는 결과가 나온다

해결 코드

public final class ATM {
    private final int money;

    private ATM(int money) {
        if (money < 0) {
            throw new IllegalArgumentException("음수의 금액은 처리할 수 없습니다.");
        }
        this.money = money;
    }

    public static ATM withMoney(int money) {
        return new ATM(money);
    }

    public ATM plus(int money) {
        return new ATM(this.money + money);
    }

    public int getMoney() {
        return money;
    }
}

돈을 넣을 떄마다 새로운 객체를 생성하기 떄문에 여러 쓰레드를 사용해도 안전하다.

불변 객체를 사용하는 이유

  • "불변 객체를 사용해라 성능상의 단점은 미미하다." - 제이슨
  • "불변 객체는 간단하고 신뢰성 있는 코드를 만들기 위한 전략이다" - 오라클 자바 튜토리얼
  • "불변 객체는 가변 객체보다 설계하고 구현하고 사용하기 쉬우며, 오류가 생길 여지도 적고 훨씬 안전하다" - 이펙티드 자바

결론

final이라는게 별거 아니라고 생각을 했었는데 좀 더 안전한 코드를 만들어주는 역할을 해주는거 같다!
물론 싱글톤 디자인패턴에도 쓰여서 final이라는 존재는 전부터 검증 되었을거 같다! 나중에 기회가 된다면 싱글톤 디자인 패턴도 공부해서 블로그에 정리하고 싶다!

profile
Backend Programmer

0개의 댓글