🖥 Новые возможности конструкторов в Java (часть 2)



Не так давно мы рассказывали про гибкие конструкторы в Java. В 23 версии Java появится возможность инициализировать поля в том же классе перед явным вызовом конструктора (JEP-482). А пока эта фича не реализована, мы вынуждены использовать вспомогательные методы, если нам необходимо проиницизировать поля.



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



Java ≤ 22:





public class Sub extends Super {



private static byte[] prepareByteArray(Certificate certificate) {

var publicKey = certificate.getPublicKey();

if (publicKey == null) throw new IllegalArgumentException(..);

return switch (publicKey) {

case RSAKey rsaKey -> ...

case DSAPublicKey dsaKey -> ...

default -> ...

};

}



public Sub(Certificate certificate) {

super(prepareByteArray(certificate));

}



}





В коде выше метод prepareByteArray выполняет необходимую подготовку аргументов. Затем этот метод вызывается внутри конструктора Sub как часть вызова super.



Java ≥ 23:



Можно будет сделать тоже самое, но без дополнительных “приседаний” в виде вынесения логики которую мы хотим выполнить в конструкторе в отдельный метод:





public class Sub extends Super {

public Sub(Certificate certificate) {

var publicKey = certificate.getPublicKey();

if (publicKey == null) throw new IllegalArgumentException(..);

byte[] certBytes = switch (publicKey) {

case RSAKey rsaKey -> ...

case DSAPublicKey dsaKey -> ...

default -> ...

};

super(certBytes);

}

}





Также иногда возникает необходимость передать одно и то же значение в несколько аргументов конструктора суперкласса. Ранее это можно было сделать только с использованием вспомогательного конструктора.



Рассмотрим пример, связанный с системой регистрации студентов в университете. У нас есть базовый класс Person, который представляет человека, и класс Student, который наследует Person. Каждый студент имеет идентификатор, который также используется в качестве номера студенческого билета и учетной записи в университете



Java ≤ 22:





class Person {

private String id;

private String accountId;



public Person(String id, String accountId) {

this.id = id;

this.accountId = accountId;

}

}



class Student extends Person {

private Student(String id) {

super(id, id); // Передача одного и того же значения дважды

}



public Student(String firstName, String lastName) {

this(generateStudentId(firstName, lastName));

}



private static String generateStudentId(String firstName, String lastName) {

// Генерация уникального идентификатора студента

return firstName + ", " + lastName + "-" + System.currentTimeMillis();

}

}





В этом примере вспомогательный конструктор Student(String id) используется для передачи одного и того же id в два аргумента конструктора суперкласса Person.



Java ≥ 23:





class Person {

private String id;

private String accountId;



public Person(String id, String accountId) {

this.id = id;

this.accountId = accountId;

}

}



class Student extends Person {

public Student(String firstName, String lastName) {

String id = generateStudentId(firstName, lastName);

super(id, id); // Передача одного и того же значения дважды

}



private static String generateStudentId(String firstName, String lastName) {

// Генерация уникального идентификатора студента

return firstName + ", " + lastName + "-" + System.currentTimeMillis();

}

}





Ставьте 🔥 если понравился пост и вы были бы рады видеть больше разборов JEP



#Java #JEP