Record 无法从构造函数中获取参数名称?

问题描述

希望了解如何在 Java 16 下使用带有反射的 Records(以及 15 个相同的行为)

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

    public RecordTest2(int id,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

有什么解决办法吗?

编辑:只是在这里加点“我”。我可以使用 java.beans 中的 @ConstructorProperties 注释。

解决方法

这是按设计工作的。通常,Java API 中的参数名称不是您可以依赖而不会更改的;它们是一个实现细节,默认情况下,编译器不会将它们保留在类文件中。

对于记录的canonical构造函数,参数名称必须与组件名称匹配,这些被认为是类公共 API 的一部分,因此被认为是稳定的。所以编译器将它们保留在类文件中,反射尽职尽责地为它们服务。记录的规范构造器是强制性的,它的形式是由语言指定的,所以它是特殊的。

对于其他构造函数,构造函数和参数名称都没有相同的意义,因此就 ParameterNames 类文件属性而言,它们被视为普通成员。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...