: 변수의 값으로 실제 값이 아닌 값이 저장된 메모리의 주소를 가지는 타입

클래스
인터페이스
배열
열거형(Enum)
참조 타입을 클래스의 인스턴스 변수로 사용 시, 사이드 이펙트 발생 우려
원본과의 참조를 끊은 복사본을 만들어 사용하는 방식으로, 원본의 변경에 의한 복사본의 예상치 못한 변경을 방지하여 안전한 코드를 만들 수 있도로 도움
class Garage {
private List<Car> cars;
public Garage(List<Car> cars) {
// 방어적 복사: 전달받은 리스트의 복사본을 생성하여 저장
this.cars = new ArrayList<>(cars);
}
public List<Car> getCars() {
// 방어적 복사: 내부 리스트의 복사본을 반환
return new ArrayList<>(cars);
}
}
public class Main {
public static void main(String[] args) {
List<Car> initialCars = new ArrayList<>();
initialCars.add(new Car("Toyota"));
initialCars.add(new Car("Honda"));
Garage garage = new Garage(initialCars);
// garage에서 반환된 리스트에 Car를 추가
List<Car> carsFromGarage = garage.getCars();
carsFromGarage.add(new Car("Ford")); // 원래 Garage의 cars에 영향을 미치지 않음
System.out.println("Original garage cars: " + garage.getCars().size()); // 2
System.out.println("Cars from garage: " + carsFromGarage.size()); // 3
}
}




System.out.println("Original garage cars: " + garage.getCars().size());
// 2
System.out.println("Cars from garage: " + carsFromGarage.size()); // 3
복사본(carsFromGarage)과 원본(initialCars)가 서로 다른 메모리 주소를 참조
하지만, 아직 외부에서 initialCars에 대한 수정 가능성이 열려있는 상태
-> 외부에서 새로운 Car객체를 추가하면 initialCars의 크기는 변경됨
-> 방지: 캡슐화
class Garage {
private List<Car> cars;
public Garage(List<Car> cars) {
// 방어적 복사 적용
this.cars = new ArrayList<>(cars);
}
public List<Car> getCars() {
//this.cars = new ArrayList<>(cars);
// 불변 리스트 반환으로 캡슐화 강화
return Collections.unmodifiableList(new ArrayList<>(cars));
}
// 리스트를 조작할 수 있는 메서드를 통해 변경을 관리
public void addCar(Car car) {
cars.add(car);
}
}
public class Main {
public static void main(String[] args) {
List<Car> initialCars = new ArrayList<>();
initialCars.add(new Car("Toyota"));
initialCars.add(new Car("Honda"));
Garage garage = new Garage(initialCars);
// 제공된 메서드를 통해서만 수정 가능
garage.addCar(new Car("Ford"));
System.out.println("Garage cars: " + garage.getCars().size()); // 3
// getCars()가 반환하는 리스트는 복사본이므로 외부 수정이 내부에 영향을 주지 않음
List<Car> carsCopy = garage.getCars();
carsCopy.add(new Car("BMW")); // 이 변경은 Garage의 cars에 영향 없음
System.out.println("Garage cars after external modification: " + garage.getCars().size()); // 3
System.out.println("CarsCopy size after adding BMW: " + carsCopy.size()); // 4
}
}





