JavaFX8中@NamedArg注释的目的是什么?

JavaFX8中@NamedArg注释的目的是什么?,java,javafx,annotations,Java,Javafx,Annotations,我想知道JavaFX8中@NamedArg注释的用例是什么 javadoc没有给我们更多的细节, Javadoc:提供有关参数名称信息的注释 在互联网上没有更多的信息,文档,例子 也许有人能帮忙 关于。注释@NamedArg允许fxmloader实例化没有零参数构造函数的类 技术背景: fxmloader使用反射创建对象。通常,如果使用与构造函数不带参数的类相对应的标记,则通过调用调用无参数构造函数的class.newInstance(),从该类创建对象 如果一个类只使用带参数的构造函数定义,那

我想知道JavaFX8中@NamedArg注释的用例是什么

javadoc没有给我们更多的细节, Javadoc:提供有关参数名称信息的注释

在互联网上没有更多的信息,文档,例子

也许有人能帮忙


关于。

注释
@NamedArg
允许
fxmloader
实例化没有零参数构造函数的类

技术背景:

fxmloader
使用反射创建对象。通常,如果使用与构造函数不带参数的类相对应的标记,则通过调用调用无参数构造函数的
class.newInstance()
,从该类创建对象

如果一个类只使用带参数的构造函数定义,那么这是有问题的。主要问题是Java语言规范不要求在运行时保留参数名称(对于方法或构造函数)。这意味着,
fxmloader
无法直接确定哪个参数具有给定名称

为了使其具体化,假设我们定义一个
Person
类,如下所示:

package application;

import javafx.beans.NamedArg;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Person {
    private final StringProperty firstName ;
    private final StringProperty lastName ;

    public Person(String firstName, String lastName) {
        this.firstName = new SimpleStringProperty(this, "firstName", firstName);
        this.lastName = new SimpleStringProperty(this, "lastName", lastName);
    }

    // methods....

}
<Person firstName="Jacob" lastName="Smith"/>
在FXML中,我们可以尝试创建一个
,如下所示:

package application;

import javafx.beans.NamedArg;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Person {
    private final StringProperty firstName ;
    private final StringProperty lastName ;

    public Person(String firstName, String lastName) {
        this.firstName = new SimpleStringProperty(this, "firstName", firstName);
        this.lastName = new SimpleStringProperty(this, "lastName", lastName);
    }

    // methods....

}
<Person firstName="Jacob" lastName="Smith"/>
如果尝试使用FXML加载此文件:

Person.fxml:

<?xml version="1.0" encoding="UTF-8"?>
<?import application.Person?>
<Person firstName="Jacob" lastName="Smith" xmlns:fx="http://javafx.com/fxml/1" />
然后您会在运行时看到一个错误:

Caused by: java.lang.NoSuchMethodException: application.Person.<init>()
这将允许
fxmloader
根据需要加载类

请注意,您还可以通过定义一个构建器类来解决这个问题,这也适用于JavaFX2.0及更高版本。JavaFX团队决定(可能是正确的)以一种不受构建器初始实现中存在的bug影响的方式使用这种方法会给框架的代码库增加太多的膨胀

package application;

public class PersonBuilder {

    private String firstName ;
    private String lastName ;

    private PersonBuilder() {   }

    public static PersonBuilder create() {
        return new PersonBuilder();
    }

    public PersonBuilder firstName(String firstName) {
        this.firstName = firstName ;
        return this ;
    }

    public PersonBuilder lastName(String lastName) {
        this.lastName = lastName ;
        return this ;
    }

    public Person build() {
        return new Person(firstName, lastName);
    }
}
显然,如果您使用的是JavaFX8,那么构造函数注释方法的工作量要少得多

参考文献:

  • (讨论构建器,但不是
    @NamedArg

谢谢你的提问。直到我看到并研究了答案,我才意识到
@NamedArgs
。我一直在想,当构建器被删除时,
fxmloader
依赖于构建器的问题将如何解决,这也回答了这个问题。有关FXML注释的完整列表,请看一看,非常感谢您提供了完整且有插图的答案,到目前为止,我必须为我的JavaFXbean定义空的无参数构造函数,它将更改并用@NamedArg清理我的代码。@James\D感谢您的详细解释!好奇的是,4年多之后,
Builder
BuilderFactory
最终被弃用了吗?为什么
请求将@NamedArgs上的文档添加到“FXML简介”文档中
被标记为wontfix(阅读文档时让我很困惑)?
package application;

public class PersonBuilder {

    private String firstName ;
    private String lastName ;

    private PersonBuilder() {   }

    public static PersonBuilder create() {
        return new PersonBuilder();
    }

    public PersonBuilder firstName(String firstName) {
        this.firstName = firstName ;
        return this ;
    }

    public PersonBuilder lastName(String lastName) {
        this.lastName = lastName ;
        return this ;
    }

    public Person build() {
        return new Person(firstName, lastName);
    }
}