不懂@ConstructorProperties

2022-09-01 10:39:40

大约@ConstructorProperties

文档说“构造函数上的注释,显示该构造函数的参数如何与构造对象的 getter 方法相对应”。它给出了一个模棱两可的例子,因为变量名与参数相同。

我真的不明白为什么指的是getters和.x 和 y 的大小写与注释不一致。@ConstructorProperties({"x", "y"})getX()getY()

因此,为了澄清此代码中构造函数的注释应是什么:

public class Point {
    public Point(int a, int b) {
       this.c = a;
       this.d = b;
   }

   public int getCc() {
       return c;
   }

   public int getDd() {
       return d;
   }

   private final int c, d;

}

(我编辑了代码,因为从答案中,我理解注释期望代码遵循getter的常见大小写约定,例如 getter 必须是 。但是我故意保持,为了消除歧义,getter名称和实际变量之间的差异返回)ccgetCc()

第二个问题...

@ConstructorProperties(value="text")

对于 JButton(字符串文本)来说,这个注释是什么意思?

它似乎可供工具使用,但只是想了解。


答案 1

@ConstructorProperties某些序列化框架使用它来将构造函数参数与相应的字段及其 gettersetter 方法相关联。

为此,它依赖于在为字段命名 getter 和 setter 方法时使用的相同常见命名约定:Getter 和 setter 方法名称通常是通过将字段的名称大写并在前缀或(或布尔 getter)前面来创建的。但是,具有单个字母字段名称的示例并不是显示此内容的最佳选择。getsetis

一个更好的例子:成为和someValuegetSomeValuesetSomeValue

因此,在构造函数属性的上下文中,意味着第一个参数与 getter 和 setter 相关联。@ConstructorProperties({"someValue"})getSomeValuesetSomeValue

请记住,方法参数名称在运行时*不可见。参数的顺序才是最重要的。构造函数参数的名称或构造函数实际设置的字段无关紧要。以下内容仍将引用名为 的方法。getSomeValue()

@ConstructorProperties({"someValue"})
public Point(int a) {
    this.c = a;
}

何时需要此注释?

JavaBeans 通常具有公共缺省构造函数(没有参数)以及所有字段的公共 getter 和 setter 方法。这意味着它们很容易序列化而没有任何注释,而且它们始终是可变的。

的用例似乎是对不遵循 JavaBeans 约定的对象进行反序列化,例如没有任何 setter 的不可变 POJO:@ConstructorProperties

对于序列化,框架使用对象 getter 获取所有值,并使用这些值序列化对象。当对象需要反序列化时,框架必须创建一个新实例。由于该对象是不可变的,因此它没有任何 setter,尽管这可以用来设置其值。构造函数是设置这些值的唯一方法。注释用于告诉框架如何调用构造函数以正确初始化对象。


* 如注释中所指出的,与 Java 8 一起发布的 JEP 118 可用于在运行时包含参数名称。此可选功能可能会使注释过时,但前提是框架支持该功能。@ConstructorProperties


答案 2