С новой функциональностью записи Java 14 возможно ли создание множественных конструкторов для одной и той же записи?

#java #record

#java #запись

Вопрос:

У меня есть куча классов «данных», использующих Lombok, и я хочу перенести их все, чтобы использовать новую функциональность записи, доступную в Java 14. С новой функциональностью записи Java 14 возможно ли создание множественных конструкторов для одной и той же записи? Если нет, есть ли альтернатива?

Ответ №1:

В Java 14 записи не могли иметь несколько конструкторов (ссылка: Java 14 — JEP 359: Записи (предварительный просмотр)).

Начиная с Java 15 и 16 , записи могут иметь несколько конструкторов. (см. Java 15 — JEP 384: Записи (второй предварительный просмотр) и Java 16 — JEP 395: записи (окончательный вариант)).

Однако каждый конструктор должен делегировать каноническому конструктору записи, который может быть явно определен или автоматически сгенерирован.

Пример:

 public record Person(
    String firstName,
    String lastName
) {
    // Compact canonical constructor:
    public Person {
        // Validations only; fields are assigned automatically.
        Objects.requireNonNull(firstName);
        Objects.requireNonNull(lastName);

        // An explicit fields assignment, like
        //   this.firstName = firstName;
        // would be a syntax error in compact-form canonical constructor
    }

    public Person(String lastName) {
        // Additional constructors MUST delegate to the canonical constructor,
        // either directly:
        this("John", lastName);
    }

    public Person() {
        // ... or indirectly:
        this("Doe");
    }
}
  

Другой пример:

 public record Person(
    String firstName,
    String lastName
) {
    // Canonical constructor isn't defined in code, 
    // so it is generated implicitly by the compiler.

    public Person(String lastName) {
        // Additional constructors still MUST delegate to the canonical constructor!
        // This works: 
        this("John", lastName);

        // (Re-)Assigning fields here directly would be a compiler error:
        // this.lastName = lastName; // ERROR: Variable 'lastName' might already have been assigned to
    }

    public Person() {
        // Delegates to Person(String), which in turn delegates to the canonical constructor: 
        this("Doe");
    }
}