- 방어적 복사에 대해서 설명해주세요.2025년 04월 17일 15시 55분 39초에 업로드 된 글입니다.작성자: do_hyuk728x90반응형
방어적 복사(Defensive Copy) 는 원본과의 참조를 끊은 복사본을 만들어 사용하는 방식이며, 원본의 변경에 의한 예상치 못한 사이드 이펙트를 방지하여 안전한 코드를 만들 수 있는데 도움이 됩니다.
방어적 복사는 2가지 시점이 존재하는데요.생성자의 인자로 받은 객체의 복사본을 만들어 내부 필드를 초기화하거나, getter 메서드에서 객체를 반환할 때, 복사본을 만들어 반환할 수 있습니다.
만약 컬렉션 자료구조를 반환하는 경우라면 자바의 Unmodifiable Collection을 사용하여, 외부에서 Collection에 대해 조회만 할 수 있도록 강제할 수 있습니다.
자바에서 Unmodifiable Collection은 set(), add(), addAll() 처럼 컬렉션에 요소를 추가하거나 변경하는 메서드를 사용하는 경우, 예외를 발생합니다.
다음 코드에서 발생할 수 있는 문제점은 무엇일까요? 🤔
public class Lotto { private final List<LottoNumber> numbers; public Lotto(List<LottoNumber> numbers) { validateSize(numbers); this.numbers = new ArrayList<>(numbers); // 방어적 복사 } }
충분히 고민해 보신 다음에 펼쳐보세요!
더보기
위 코드는 두 가지 문제점이 발생할 수 있습니다.
첫 번째는 생성자의 파라미터로 주어진 LottoNumber 리스트의 각 요소가 외부에서 변경될 수 있는 가능성이 존재합니다. 이러한 문제가 발생하는 이유는 방어적 복사가 깊은 복사가 아니기 때문입니다. 가령, 외부에서 다음과 같은 코드를 작성할 수 있습니다.Lotto lotto = new Lotto(numbers); numbers.get(0).changeNumber(1);
이 문제를 해결하기 위해서는 생성자의 파라미터에 Integer 리스트를 입력받거나, 방어적 복사 수행 시 내부 객체까지 깊은 복사를 수행할 수 있습니다.
또한 위 코드는 검증을 수행하는 시점에 외부에서 컬렉션이 변경이 발생할 수 있는 가능성이 존재합니다. 예를 들어, validateSize 메서드를 통과하고 방어적 복사를 수행하기 전에 외부에서 numbers에 값을 추가하는 경우, 검증은 성공했지만 객체의 값은 유효하지 않을 수 있습니다. 이 잠재적인 문제를 해결하기 위해서는 방어적 복사가 검증이 수행되기 이전에 이루어져야 합니다.728x90반응형'면접 대비' 카테고리의 다른 글
JVM에서 GC 대상 객체를 판단하는 기준은 무엇인가요? (0) 2025.05.04 어떤 예외가 발생하면 트랜잭션을 롤백하나요? (1) 2025.05.02 Call By Value와 Call By Reference에 대해서 설명해주세요. (0) 2025.04.16 자바 프로그램이 실행되는 흐름을 설명해 주세요. (1) 2025.04.09 교착 상태에 대해서 설명해주세요. (0) 2025.04.01 댓글