코드 한 줄의 기록

Java 객체 생성 완벽 가이드: 생성자, 정적 팩토리 메서드, 생성자 체이닝 총정리 본문

JAVA

Java 객체 생성 완벽 가이드: 생성자, 정적 팩토리 메서드, 생성자 체이닝 총정리

CodeByJin 2025. 10. 9. 08:10
반응형

이 글에서는 Java에서 객체를 생성하는 주요 기법인 생성자(Constructor), 정적 팩토리 메서드(Static Factory Method), 그리고 생성자 체이닝(Constructor Chaining)을 예제 중심으로 쉽고 자연스럽게 소개합니다. 직접 코드를 작성해보며 장·단점을 비교하고, 언제 어떤 방식을 선택하면 좋은지 실전 팁까지 정리했습니다.

Java 객체 생성 기본: 생성자(Constructor)

생성자의 개념과 역할

Java 클래스는 인스턴스를 만들기 위해 생성자를 사용합니다. 생성자는 클래스 이름과 동일한 특별한 메서드로, 객체 초기화 책임을 가집니다. 반환 타입이 없으며, new 키워드를 통해 호출합니다.

public class User {
    private String name;
    private int age;

    // 기본 생성자
    public User() {
        this.name = "Anonymous";
        this.age = 0;
    }

    // 매개변수를 받는 생성자
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
  • 기본 생성자(Default Constructor): 매개변수가 없는 생성자로, 멤버 변수의 기본값을 설정합니다.
  • 매개변수 생성자(Parameter Constructor): 객체 생성 시 중요한 초기값을 직접 주입할 때 사용합니다.

생성자 오버로딩(Constructor Overloading)

여러 종류의 생성자를 정의해 다양한 초기화 옵션을 제공합니다.

public class Product {
    private String id;
    private String name;
    private double price;

    public Product() {
        this("000", "Unknown", 0.0);
    }

    public Product(String id) {
        this(id, "Unnamed", 0.0);
    }

    public Product(String id, String name) {
        this(id, name, 0.0);
    }

    public Product(String id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
}

 

오버로딩을 통해 다양성을 제공하면서도 코드 중복을 줄일 수 있습니다. 위 예제에서는 생성자 체이닝(this(...))을 활용했습니다.

생성자 체이닝(Constructor Chaining)

this(...)를 이용한 내부 호출

하나의 생성자에서 다른 생성자를 호출해 공통 초기화 코드를 재활용하는 기법입니다.

public class Book {
    private String title;
    private String author;
    private int year;

    public Book() {
        this("Unknown Title", "Unknown Author", 0);
    }

    public Book(String title) {
        this(title, "Unknown Author", 0);
    }

    public Book(String title, String author) {
        this(title, author, 0);
    }

    public Book(String title, String author, int year) {
        this.title = title;
        this.author = author;
        this.year = year;
    }
}
  • 장점: 초기화 로직 중복을 제거하고, 코드 가독성과 유지보수성을 높입니다.
  • 주의점: this(...) 호출은 반드시 생성자 첫줄에 위치해야 합니다.

super(...)를 이용한 상위 클래스 생성자 호출

상속 관계에서 상위 클래스 생성자를 명시적으로 호출해 부모 필드를 초기화합니다.

public class Animal {
    protected String species;

    public Animal(String species) {
        this.species = species;
    }
}

public class Dog extends Animal {
    private String name;

    public Dog(String name) {
        super("Canine");
        this.name = name;
    }
}
  • super(...)는 생성자 첫 줄에서 호출해야 하며, 생략 시 컴파일러가 자동으로 기본 생성자를 호출합니다.

정적 팩토리 메서드(Static Factory Method)

정의와 장·단점

정적 팩토리 메서드는 생성자 대신 정적 메서드로 객체를 반환합니다.

public class Connection {
    private String url;

    private Connection(String url) {
        this.url = url;
    }

    // 정적 팩토리 메서드
    public static Connection of(String url) {
        return new Connection(url);
    }
}
  • 장점
    • 이름 지정 가능: of(), valueOf(), getInstance() 등 직관적인 이름으로 의도를 드러냄.
    • 재사용 가능한 인스턴스: 캐싱, 싱글톤 패턴 구현 용이.
    • 반환 타입 유연성: 서브클래스 인스턴스를 반환하거나 인터페이스 타입 반환 가능.
  • 단점
    • 상속 제약: 생성자가 private이면 서브클래스에서 재사용 불가능.
    • API 복잡도: 다양한 팩토리 메서드로 오히려 혼란 초래 가능.

Java 표준 라이브러리 활용 예

  • Integer.valueOf(int)
  • EnumSet.of(...)
  • Collectors.toList()
List<String> list = Collections.emptyList();
Integer i = Integer.valueOf("123");

언제 어떤 방식을 선택할까?

가독성단순하고 익숙함메서드 이름으로 의도 명확생성자 중복 제거
확장성제한적서브클래스 인스턴스 반환 가능상속 시 super() 사용
싱글톤/캐싱불가능가능별도 구현 필요
오버로딩가능가능가능
  • 일반 POJO: 복잡하지 않으면 기본 생성자로 충분.
  • 다양한 초기화 로직: 생성자 체이닝으로 중복 회피.
  • API 설계 시: 의미 있는 이름과 캐싱이 필요하면 정적 팩토리 메서드.

실전 팁 및 주의사항

  1. 불변 객체 설계
    생성자와 정적 팩토리 메서드를 활용해 final 필드로 설계하여 안전성을 높일 수 있습니다.
  2. 가독성 유지
    생성자 체이닝이 과도하면 호출 흐름 파악이 어려워지므로 최대 3단계 이내로 제한하세요.
  3. 문서화
    정적 팩토리 메서드는 이름으로 역할을 드러내되, Javadoc으로 반환 타입과 캐싱 여부를 명확히 설명하세요.
  4. 예외 처리
    잘못된 매개변수를 받을 가능성이 있으면 IllegalArgumentException 등을 통해 실패를 빠르게 알리세요.

Java에서 객체 생성 방식은 생성자, 정적 팩토리 메서드, 생성자 체이닝 세 축을 이해하고 상황에 맞게 조합하여 사용하면 코드의 안정성과 가독성을 동시에 높일 수 있습니다. 이번 글을 따라 직접 예제를 구현해보면서, 각 기법의 장·단점을 체험해보세요. 잘 설계된 객체 생성 패턴은 유지보수성과 확장성을 크게 향상시킬 것입니다.

Java 캡슐화와 접근 제어자 완벽 가이드: 불변 객체 패턴 기초부터 활용까지

Java 개발자가 반드시 알아야 할 캡슐화(encapsulation) 개념과 접근 제어자(access modifier), 그리고 불변 객체(immutable object) 패턴의 기초를 함께 살펴봅니다.캡슐화(Encapsulation)란 무엇인가?캡슐화는 객

byteandbit.tistory.com

반응형