생성자 어노테이션

김상훈·2024년 11월 18일

Spring Boot

목록 보기
2/2

개요

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/users")
public class UserController {

    private final UserService userService;

    @GetMapping("/{userId}")
    public UserInfoResponse getUserById(@PathVariable String userId) {
      return userService.getUserById(userId)
    }

    ...   
}

문득 개발을 하다가 @~ArgsConstructor에 대해 궁금증이 생겼다.

자연스럽게 필요한 코드에 해당 어노테이션들을 달지만 왜 달아야하는지 다시 공부한다.

간단하게 말하면 해당 어노테이션들은 다음과 같다.

  • @NoArgsConstructor: parameter가 없는 default 생성자를 생성

  • @AllArgsConstructor: 모든 field 값을 paramter로 받는 생성자를 생성

  • @RequiredArgsConstructor: final이나 @NonNull로 선언된 field만을 paramter로 받는 생성자를 생성

이 어노테이션들은 객체 내부에 선언되어있는 특정 field마다 딱 1개의 값을 생성자 parameter로 받고, 이 값을 단순히 field에 assign 해주는 생성자를 생성한다.

각 생성자들의 특징

@NoArgsConstructor

@NoArgsConstructor을 사용하면, class에 명시적으로 선언된 생성자가 없더라도 instance를 생성할 수 있다.

@NoArgsConstructor
public class User {
  
  private String userName;
  private String userEmail;
}

위의 코드를 빌드하면 다음과 같아진다.

public class User {

  private String userName;
  private String userEmail;
  
  public User(){}
}

@AllArgsConstructor

@AllArgsConstructor을 사용하면, class의 모든 field를 한 번에 초기화할 수 있다.

@AllArgsConstructor
public class User {
  
  private String userName;
  private String userEmail;
}

위의 코드를 빌드하면 다음과 같아진다.

public class User {
  
  private String userName;
  private String userEmail;
  
  public User(String userName, String userEmail) {
    this.userName = userName;
    this.userEmail = userEmail;
  }
}

@RequiredArgsConstructor

@RequiredArgsConstructor을 사용하면, class가 의존하는 field를 간단하게 초기화할 수 있다.

※ final로 선언하면 한 번 초기화된 변수는 변경할 수 없는 상수값이 된다. → 불변성 유지

(단, 객체를 final로 선언하면 다른 객체로 변경할 수는 없지만 객체의 속성은 변경 가능하다.)

@RequiredArgsConstructor
public class User {
  
  private final String userName;
  private final String userEmail;
}

위의 코드를 빌드하면 다음과 같아진다.

public class User {

  private String userName;
  private String userEmail;
  
  public User(final String userName, final String userEmail) {
    this.userName = userName;
    this.userEmail = userEmail;
  }
}

생성자 어노테이션의 옵션

또한 생성자 어노테이션에는 다음과 같은 옵션들이 있다.

  • staticName: 정적 팩토리 메서드를 생성

  • access: 접근제어자를 지정 (default: public)

  • onConstructor: 생성자의 접근제어자를 설정 (default: public)

  • force: final field가 선언된 경우 compile 타임에 기본값을 0 / null / false로 설정

staticName

모든 생성자 어노테이션에 사용될 수 있다.

@AllArgsConstructor(staticName = "of")
public class User {
  
  private String userName;
  private String userEmail;
}

위의 코드를 빌드하면 다음과 같아진다.

@AllArgsConstructor(staticName = "of")
public class User {
  
  private String userName;
  private String userEmail;
  
  public static User of(String userName, String userEmail) {
    new User(userName, userEmail);
  }
}

access

access 옵션엔 다음과 같은 접근제어자가 있다.

  • PUBLIC: 모든 클래스에서 생성자에 접근 가능

  • PROTECTED: 같은 패키지의 클래스와 상속받은 클래스에서 생성자에 접근 가능

  • PACKAGE: 같은 패키지의 클래스에서 생성자에 접근 가능

  • PRIVATE: 해당 클래스 내부에서만 생성자에 접근 가능
    ※ NONE과 MODULE도 있지만, 일반적으로 사용하지 않는다.

force

@NoArgsConstructor 어노테이션에만 사용이 가능하다. force 옵션을 지정할 경우 primitive type에 맞는 기본값이 설정된다.

@NoArgsConstructor(force = true)
public class User {
  
  private final String userName;
  private final int userAge;
  private String userEmail;
}

위의 코드는 compile 시점에 다음과 같아진다.

public class User {
  
  private final String userName = null;
  private final int userAge = 0;
  private String userEmail;
}

0개의 댓글