← Назад к вопросам

В чем разница между @AllArgsConstructor и @RequiredArgsConstructor?

1.0 Junior🔥 191 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Разница между @AllArgsConstructor и @RequiredArgsConstructor

Краткое сравнение

АннотацияПараметры конструктора
@AllArgsConstructorВсе поля класса
@RequiredArgsConstructorТолько final поля и поля с @NonNull

Подробно

@AllArgsConstructor

Создаёт конструктор с параметрами для всех полей класса.

@AllArgsConstructor
public class User {
    private String name;
    private String email;
    private int age;
}

// Эквивалентно:
public class User {
    private String name;
    private String email;
    private int age;
    
    public User(String name, String email, int age) {
        this.name = name;
        this.email = email;
        this.age = age;
    }
}

// Использование:
User user = new User("Alice", "alice@mail.com", 30);

@RequiredArgsConstructor

Создаёт конструктор только с параметрами для:

  1. final полей (обязательные для инициализации)
  2. Полей с @NonNull (требуют check)
@RequiredArgsConstructor
public class User {
    private final String name;           // ← включится в конструктор
    @NonNull
    private String email;                // ← включится в конструктор
    private int age;                     // ← НЕ включится
}

// Эквивалентно:
public class User {
    private final String name;
    @NonNull
    private String email;
    private int age;
    
    public User(String name, @NonNull String email) {
        if (email == null) {
            throw new NullPointerException("email is marked as non-null but is null");
        }
        this.name = name;
        this.email = email;
        // age НЕ инициализируется, остаётся 0
    }
}

// Использование:
User user = new User("Alice", "alice@mail.com");
// age остаётся 0 (default value для int)

Практические примеры

Пример 1: Dependency Injection (Spring)

Для Spring бинов часто используют @RequiredArgsConstructor:

@Service
@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepository;  // ← обязательно
    private final EmailService emailService;      // ← обязательно
    private final Logger logger;                  // ← обязательно
    
    public void createUser(String email) {
        User user = userRepository.save(new User(email));
        emailService.sendWelcome(user);
    }
}

// Создаётся конструктор:
public UserService(
    UserRepository userRepository,
    EmailService emailService,
    Logger logger
) { ... }

Это предпочтительно потому что:

  • Все зависимости явные
  • Невозможно создать недополученный сервис
  • Легко тестировать (mock зависимости)

Пример 2: Entity (JPA)

Для JPA entity часто используют @AllArgsConstructor:

@Entity
@AllArgsConstructor
@NoArgsConstructor  // JPA требует no-arg конструктор
public class Product {
    @Id
    private Long id;
    private String name;
    private BigDecimal price;
    private String description;
}

// Можешь создавать с полными данными:
Product product = new Product(1L, "Laptop", new BigDecimal("999.99"), "High-performance");

Но такой подход небезопасен при добавлении новых полей!

Пример 3: Immutable Data Class

@RequiredArgsConstructor + final поля = идеально:

@RequiredArgsConstructor
@Getter
public class OrderRequest {
    private final String orderId;
    private final LocalDateTime createdAt;
    @NonNull
    private final List<Item> items;
}

// Конструктор требует все обязательные поля
OrderRequest request = new OrderRequest(
    "ORDER-123",
    LocalDateTime.now(),
    List.of(new Item("SKU1", 2))
);

Сравнение сценариев

Сценарий 1: Добавляешь новое поле

С @AllArgsConstructor (опасно!):

@AllArgsConstructor
public class User {
    private String name;
    private String email;
    // Добавляем новое поле
    private String phone;  // ← новое
}

// ПРОБЛЕМА: старый код сломается!
User user = new User("Alice", "alice@mail.com");
// Ошибка компиляции! Нужны 3 параметра, а не 2

С @RequiredArgsConstructor (безопаснее!):

@RequiredArgsConstructor
public class User {
    @NonNull
    private String name;
    @NonNull
    private String email;
    // Добавляем новое поле
    private String phone;  // ← новое, не требуется конструктору
}

// Старый код ещё работает!
User user = new User("Alice", "alice@mail.com");
// ОК! phone = null

Сценарий 2: Множество полей

@AllArgsConstructor с 15 параметрами:

@AllArgsConstructor
public class ComplexEntity {
    private String field1;
    private String field2;
    // ... 13 ещё полей ...
    private String field15;
}

// Использование (кошмар!):
ComplexEntity entity = new ComplexEntity(
    "val1", "val2", "val3", "val4", "val5",
    "val6", "val7", "val8", "val9", "val10",
    "val11", "val12", "val13", "val14", "val15"
);
// Невозможно читать! Какой параметр что-то?

Лучше использовать Builder:

@Builder
@Data
public class ComplexEntity {
    private String field1;
    private String field2;
    // ... остальные ...
}

// Использование (ясно!):
ComplexEntity entity = ComplexEntity.builder()
    .field1("val1")
    .field2("val2")
    // ... остальные ...
    .build();

Рекомендации

Используй @RequiredArgsConstructor, если:

  • Spring Service/Component — обязательно

    • Все зависимости явные
    • Защита от null
    • Легко тестировать
  • Immutable class — желательно

    • final поля требуют инициализации
    • @NonNull для проверки
  • Много полей — да

    • Не создаёшь конструктор с 10+ параметрами
    • Явность какие поля требуются

Используй @AllArgsConstructor, если:

  • JPA Entity — возможно, но добавь @NoArgsConstructor

    • Но рискуешь при добавлении полей
  • DTO с мало полями (2-3) — может быть

    • Все равно используй Builder

Используй @Builder вместо обоих, если:

  • Много полей (> 3-4)
    • Readable
    • Безопасно добавлять новые поля
    • Сразу видны все параметры

Интересный момент: Order Значение

@RequiredArgsConstructor
public class Payment {
    private final String paymentId;      // Позиция 1
    private final BigDecimal amount;      // Позиция 2
    @NonNull
    private String status;               // Позиция 3
    private LocalDateTime createdAt;      // Не в конструктуре
}

// Конструктор в порядке объявления!
public Payment(
    String paymentId,    // Позиция 1
    BigDecimal amount,   // Позиция 2
    String status       // Позиция 3
) { ... }

Итоговый ответ

  • @AllArgsConstructor = конструктор для ВСЕХ полей (опасен при изменениях)
  • @RequiredArgsConstructor = конструктор только для final + @NonNull (безопаснее)

Для Spring Services используй @RequiredArgsConstructor, для больших объектов используй @Builder!

В чем разница между @AllArgsConstructor и @RequiredArgsConstructor? | PrepBro