평범한 연구소

JAVA 생성자, 디폴트 생성자, 생성자 오버로딩 본문

JAVA/기본 개념

JAVA 생성자, 디폴트 생성자, 생성자 오버로딩

soyeonisgood 2025. 3. 6. 20:12

프로젝트 진행 중 디폴트 생성자 관련 버그를 해결하며... 기본 개념을 복습하고자 작성한다! 

 

1. 생성자 Constructor

  • 객체가 생성될 때 초기화를 담당하는 메서드
  • new 키워드를 사용

2. 생성자의 특징

  • 클래스명과 동일한 이름을 가진다
  • 반환 타입이 없다 (void도 아님)
  • 객체가 생성될 때 자동으로 한 번 호출된다

3. 생성자의 종류 

3-1. 디폴트 생성자 (Default Constructor)

  • 매개변수가 없는 생성자
  • 클래스에 생성자가 없으면 컴파일러가 자동으로 기본 생성자를 만든다. 
public class Student {
    private String name;
    private String email;
    private int age;
    
    public Student() {
        this.name = "사용자";
        this.email = "@gmail.com";
        this.age = 0;
    }
}

 

3-2. 매개변수가 있는 생성자

  • 객체 생성 시 특정 값으로 초기화하기 위해 매개변수가 있는 생성자 정의 가능 
public class Student {
    private String name;
    private String email;
    private int age;
    
    // 매개변수가 있는 생성자
    public Student(String name, String email, int age) {
        this.name = name;
        this.email = email;
        this.age = age;
    }
}



Student student = new Student("주니모", "syjeong@gmail.com", 28);

 

3-3. 생성자 오버로딩 (Constructor Overloading)

  • 클래스 내에 여러 개의 생성자를 정의하는 것
  • 매개변수 개수나 타입이 다른 여러 생성자를 만들면 다양한 초기화 방법을 사용할 수 있음
public class Student {
    private String name;
    private int age;
    private String major;
    
    // 기본 생성자
    public Student() {
        this.name = "Unknown";
        this.age = 0;
        this.major = "Undecided";
    }
    
    // 이름만 초기화하는 생성자
    public Student(String name) {
        this.name = name;
        this.age = 0;
        this.major = "Undecided";
    }
    
    // 이름과 나이를 초기화하는 생성자
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
        this.major = "Undecided";
    }
    
    // 모든 필드를 초기화하는 생성자
    public Student(String name, int age, String major) {
        this.name = name;
        this.age = age;
        this.major = major;
    }
}

 

4. this() 키워드를 이용한 생성자 체이닝

  • 생성자 내에서 this() 키워드를 사용하여 같은 클래스의 다른 생성자를 호출할 수 있다.
  • 이를 통해 코드 중복을 줄이고 유지보수성을 높일 수 있다.
public class Student {
    private String name;
    private int age;
    private String major;
    
    // 기본 생성자
    public Student() {
        this("Unknown", 0, "Undecided");
    }
    
    // 이름만 초기화하는 생성자
    public Student(String name) {
        this(name, 0, "Undecided");
    }
    
    // 이름과 나이를 초기화하는 생성자
    public Student(String name, int age) {
        this(name, age, "Undecided");
    }
    
    // 모든 필드를 초기화하는 생성자
    public Student(String name, int age, String major) {
        this.name = name;
        this.age = age;
        this.major = major;
    }
}

 

 

5. 생성자 사용 시 주의사항

5-1. 매개변수 순서의 중요성

  • 나의 경우, 객체 5번째 필드 status, 6번째 필드 type의 디폴트 생성자를 이용하여 초기화 할 때, 5번째 파라미터에 type을, 6번째 파라미터에 status를 넣는 실수를 하고 말았다 ^.^;; 둘 다 String 타입이었어서 테스트 중에 발견했다
  • 아래는 이에 대한 예시
public class Person {
    private String name;
    private String email;
    private int age;
}

// 객체 필드인 name과 email의 순서와 다르다!
new Person("syjeong@gmail.com", "주니모", 28);

 

6. 생성자 대안 패턴

6-1. 정적 팩토리 메서드 (Static Factory Method)

  • 메서드명을 통해 생성 의도를 명확화 할 수 있다.
public class Color {
    private int red;
    private int green;
    private int blue;
    
    private Color(int red, int green, int blue) {
        this.red = red;
        this.green = green;
        this.blue = blue;
    }
    
    // 정적 팩토리 메소드
    public static Color createRed() {
        return new Color(255, 0, 0);
    }
    
    public static Color createGreen() {
        return new Color(0, 255, 0);
    }
    
    public static Color createBlue() {
        return new Color(0, 0, 255);
    }
    
    public static Color fromRGB(int red, int green, int blue) {
        return new Color(red, green, blue);
    }
}

// 사용 예
Color red = Color.createRed();
Color customColor = Color.fromRGB(100, 150, 200);

 

6-2. 빌더 패턴 (Builder Pattern)

  • 객체의 필드가 많은 경우 가독성을 높이고 순서 혼동을 방지할 수 있다. 
public class Person {
    private final String firstName;   // 필수
    private final String lastName;    // 필수
    private final int age;            // 선택
    private final String phone;       // 선택
    private final String address;     // 선택
    
    private Person(Builder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.phone = builder.phone;
        this.address = builder.address;
    }
    
    public static class Builder {
        private final String firstName;   // 필수
        private final String lastName;    // 필수
        private int age = 0;              // 선택, 기본값
        private String phone = "";        // 선택, 기본값
        private String address = "";      // 선택, 기본값
        
        public Builder(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }
        
        public Builder age(int age) {
            this.age = age;
            return this;
        }
        
        public Builder phone(String phone) {
            this.phone = phone;
            return this;
        }
        
        public Builder address(String address) {
            this.address = address;
            return this;
        }
        
        public Person build() {
            return new Person(this);
        }
    }
}

// 사용 예
Person person = new Person.Builder("홍", "길동")
                    .age(30)
                    .phone("010-1234-5678")
                    .address("서울시 강남구")
                    .build();

 

 

7. Lombok 라이브러리 활용

  • 생성자와 관련된 유용한 어노테이션을 제공하는 라이브러리 Lombok을 활용해보자.

7-1. @NoArgsConstructor

  • 매개변수가 없는 디폴트 생성자를 자동으로 생성해준다.
import lombok.NoArgsConstructor;

@NoArgsConstructor
public class User {
    private String username;
    private String email;
    
    // Lombok이 다음과 같은 생성자를 자동 생성:
    // public User() {
    // }
}

 

7-2. @AllArgsConstructor

  • 모든 필드를 매개변수로 받는 생성자 자동으로 생성
import lombok.AllArgsConstructor;

@AllArgsConstructor
public class User {
    private String username;
    private String email;
    
    // Lombok이 다음과 같은 생성자를 자동 생성:
    // public User(String username, String email) {
    //     this.username = username;
    //     this.email = email;
    // }
}

 

7-3. @RequiredArgsConstructor

  • final 필드나 @NonNull로 표시된 필드만을 매개변수로 받는 생성자를 자동으로 생성
import lombok.RequiredArgsConstructor;
import lombok.NonNull;

@RequiredArgsConstructor
public class User {
    private final String username;  // final 필드
    @NonNull private String email;  // @NonNull 필드
    private int age;                // 일반 필드 (생성자에 포함되지 않음)
    
    // Lombok이 다음과 같은 생성자를 자동 생성:
    // public User(String username, String email) {
    //     this.username = username;
    //     if (email == null) throw new NullPointerException("email");
    //     this.email = email;
    // }
}

 

 

위 어노테이션은 일반적으로 @Builder과 함께 사용한다 :)