Запись не может получить имена параметров из конструкторов?

Хотите узнать, как использовать записи с отражением в Java 16 (и 15 такое же поведение)

      public record RecordTest2(int id, int something, double total, LocalDateTime createdOn) {

    public RecordTest2(int id, int something, double total) {
        this(id, something, total, LocalDateTime.now());
    }
}

Глядя на дефолт? основной конструктор? Я вижу имена параметров, но не вижу других.

      var recordTest2 = new RecordTest2(1, 2, 3.0, LocalDateTime.now());
Class<?> objectClass = recordTest2.getClass();

Constructor<?>[] constructors = objectClass.getConstructors();

for (Constructor<?> con : constructors) {
    System.out.println(con.getName());
    Parameter[] parameters = con.getParameters();
    for (Parameter parameter : parameters) {
        System.out.printf("param: %s\n", parameter.getName());
    }
}

выход:

      net.sf.persism.dao.records.RecordTest2
param: arg0
param: arg1
param: arg2
net.sf.persism.dao.records.RecordTest2
param: id
param: something
param: total
param: createdOn

Есть ли способ обойти это?

1 ответ

Это работает так, как задумано. Имена параметров в API Java, как правило, не являются чем-то, на что можно положиться; они являются деталями реализации, и по умолчанию компилятор не сохраняет их в файле классов.

Для канонического конструктора записи имена параметров должны соответствовать именам компонентов, и они считаются частью общедоступного API классов и, следовательно, считаются стабильными. Таким образом, компилятор сохраняет их в файле классов, а отражение должным образом их обслуживает. Канонический конструктор записи является обязательным, а его форма определяется языком, поэтому в этом смысле он особенный.

Для других конструкторов ни конструкторы, ни имена параметров не имеют одинакового значения, поэтому они рассматриваются как обычные члены для целей ParameterNames атрибут classfile.

Другие вопросы по тегам