Не так давно мы рассказывали про гибкие конструкторы в 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