[Java] 불변 클래스와 final 클래스

벼랑 끝 코딩·2025년 2월 25일
0

Java

목록 보기
19/40

객체의 데이터가 변경되는 것은
때로는 매우 위험한 일이다.
그래서 우리는 객체를 변경할 수 없도록
불변 클래스를 설계하곤 한다.

final 키워드를 이용하면 더 이상 수정이 불가능 하댔지.
그럼 class에 final을 붙이면 되는건가?
그렇지 않다.

불변 클래스와 final 클래스의 차이를 알아보자.

final 클래스

final class Clazz {
	// 코드
}

final 클래스는 class 키워드 앞에 final 키워드를 붙여서 사용이 가능하다.
final 키워드는 변경하지 못하도록 만드는 키워드였으니,
final class는 변경이 불가능한 클래스인 것인가?

그렇지 않다. final class는 변경이 가능하다
그럼 여기서 final은 무슨 역할을 하는가?
class의 앞 final은 상속을 불가능하게 만든다.

final class Parent {
	String name;
    int age;
    
	// 코드
}

class Child extends Parent { // ** 불가 **
	// 코드
}

final 키워드와 함께 선언된 class는 상속이 불가능하지만
내부의 필드는 여전히 변경 가능하다.
final 키워드가 붙었다고 해서 오해해선 안된다.

불변 클래스

객체의 데이터가 변하는 것을 막기 위해
불변 클래스를 만들고자 한다.
그래서 final 키워드를 사용하려고 했더니, 그게 아니었다.
그렇다면 불변 클래스는 어떻게 만드는 것인가?

final 필드 선언

class Clazz {
	final int value; // ** final 키워드 사용 **
    
    public Clazz(int value) {
    	this.value = value;
    }
}   	

객체의 데이터를 수정하지 못하도록 필드에 final을 선언해주면 된다.
이 필드는 생성자를 통하여 최초 1회 초기화한 이후,
더 이상 데이터를 수정할 수 없다.

set() 메서드 삭제

필드에는 보통 get(), set() 메서드가 존재한다.
하지만 객체의 데이터 변경을 제한하고 싶은 경우,
set() 메서드를 삭제하여 데이터 변경을 막는다.

class Clazz {
	final int value; // ** final 키워드 사용 **
    
    public Clazz(int value) {
    	this.value = value;
    }
    
    public int getValue() {
    	return value;
    }
    
    // ** set() 메서드는 삭제
    public void setValue(int value) {
    	this.value += value;
    }
}   

불변 클래스 값 변경

객체의 데이터가 변경되는 것이 싫어 불변 클래스를 만들었지만
그래도 데이터를 변경해야 하는 순간이 필요할 수 있다.
그 때는 새로운 객체를 생성해주면 된다.

class Clazz {
	final int value; // ** final 키워드 사용 **
    
    public Clazz(int value) {
    	this.value = value;
    }
    
    public Clazz withValue(int value) {
    	return new Clazz(value);
    }
}   

with

참고로 불변 객체에서 값을 변경하려고 하는 경우,
다음과 같이 메서드 이름을 with으로 시작하는 것이 관례이다.

public Clazz withValue(int value) {
    	return new Clazz(value);
    }

마무리

오해할 수 있는 불변 클래스와 final 클래스에 대해 알아봤다.
데이터 변경의 위험성을 인식하고,
불변 클래스를 만드는 것을 이해하면 더 나은 구조를 설계할 수 있겠다.

profile
복습에 대한 비판과 지적을 부탁드립니다

0개의 댓글