개발자로 후회없는 삶 살기
[Java] Java의 immutable 본문
서론
자바에서는 데이터에 변경이나 추가를 하지 못하도록 불변을 설정할 수 있는 메서드를 제공합니다. 이번 시간에는 자바의 불변에 대해 알아봅니다.
본론
- 복제본에 변화를 준 경우
먼저 복제본에 변화를 줄 수 있는지 없는지 살펴보겠습니다.
-> 배열을 입력받아 배열을 반환하는 메서드
1. Arrays.copyOf
이것은 배열을 복제하여 배열을 반환하는 메서드입니다. 복제본에 변화를 주어도 변경이 가능합니다.
-> 배열을 입력받아 List를 반환하는 메서드
1. List.of
변경 불가를 보장합니다.
2. Arrays.asList
변경은 가능하고
추가는 불가합니다.
-> List를 입력 받아 List를 반환하는 메서드
1. Collections.unmodifiableList
복제본에 변경이 불가합니다.
2. List.copyOf
복제본에 변경이 불가합니다.
- 원본의 변화
이번에는 원본에 변화를 줬을 때 참조로 인해 복제본에 변화가 가는지 살펴보겠습니다.
-> 배열을 입력받아 배열을 반환하는 메서드
1. Arrays.copyOf
이것은 아에 배열을 새로 만들어 원본과의 참조를 끊어 원본에 변화를 주어도 복제본에 영향이 없습니다.
-> 배열을 입력받아 List를 반환하는 메서드
1. List.of
원본이 변해도 복제본은 영향을 받지 않습니다.
2. Arrays.asList
원본이 바뀌면 복제본도 변합니다.
-> List를 입력 받아 List를 반환하는 메서드
1. Collections.unmodifiableList
이것은 원본과 참조하여 원본의 데이터가 변하면 복사 데이터도 변합니다.
2. List.copyOf
원본이 변하더라도 복제본은 변하지 않습니다.
변경 가능한 List 만들기 ✅
List<Integer> list = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6))
새로운 리스트 객체를 만들어 복사하면 변경이 가능합니다. 이를 활용하는 것을 2가지 경우로 나누어 보겠습니다.
1. 원본은 변경 가능, 복사본을 변경 불가능
class Cars {
private final List<Car> cars;
public Cars(final List<Car> cars) {
this.cars = Collections.unmodifiableList(new ArrayList<>(cars));
}
public int getSize() {
return cars.size();
}
}
한 번 감싸서 원본과 참조를 끊어서 immutable을 보장하는 방어적 복사를 할 수 있습니다. 이렇게 하면 원본에 변화가 일어나도 복사본은 변경이 일어나지 않고 복사본의 자체 수정도 불가합니다.
2. 원본은 변경 불가, 복사본은 변경 가능
때로는 복사 불가능한 원본에 복사본을 변경해야 할 때가 있습니다. 원본은 immutable을 보장하여 안전하게하고 복사본으로는 결과를 위한 계산을 하는 상황입니다.
1) 원본
public class Lotto {
private final List<Integer> numbers;
public Lotto(final List<Integer> numbers) {
this.numbers = Collections.unmodifiableList(numbers);
}
원본에 초기화를 할 때는 변경 못하게 하고
public List<Integer> getNumbers() {
return new ArrayList<>(numbers);
}
반환할 때 새로운 리스트 객체를 만듭니다.
2) 복제본
private int getCollectCnt(List<Integer> lottoNumbers, List<Integer> answerNumbers) {
lottoNumbers.retainAll(answerNumbers);
}
이렇게 하면 다른 곳에서 lottoNumbers에 결과를 계산하기 위한 수정을 해야할 때 원본의 불변을 보장하며 변경할 수 있습니다.
결론
자바의 불변에 대해 알아보면서 참조로 인해 변경도 알아보았습니다. 웹 어플리케이션에서 getter를 사용할 때 불변으로 주는 것이 관례인데 그때 적절한 메서드를 사용해서 반환해야 합니다.
'[백엔드] > [spring+JPA | 이슈해결]' 카테고리의 다른 글
spring PART.postman으로 login 테스트 할 때 받아온 토큰을 요청 헤더에 자동으로 넣는 방법 (0) | 2023.08.18 |
---|---|
spring PART.Value Object와 Custom Validator를 이용한 검증 개선 (0) | 2023.07.21 |
(작성중) spring PART.로컬 호스트에서 spring 서버와 flask 서버 통신하기 (0) | 2023.06.16 |
spring PART.JPA 사용하지 않고 enum 타입 DB에 저장하기 (0) | 2023.06.14 |
[spring] equals()와 hashCode()를 재정의 해야하는 이유 (0) | 2023.05.03 |