Java 摘要3在创建对象时调用构造函数两次

Java 摘要3在创建对象时调用构造函数两次,java,apache-commons-digester,Java,Apache Commons Digester,消化池里有一种奇怪的行为,我无法控制 我有以下代码,在输入xml中遇到“角色/角色”节点时调用“角色”对象的构造函数: AbstractRulesModule loader = (new AbstractRulesModule() { protected void configure() { forPattern("roles/role").createObject().ofType(Role.class)

消化池里有一种奇怪的行为,我无法控制

我有以下代码,在输入xml中遇到“角色/角色”节点时调用“角色”对象的构造函数:

        AbstractRulesModule loader = (new AbstractRulesModule() {

        protected void configure() {
            forPattern("roles/role").createObject().ofType(Role.class)
                    .usingConstructor(String.class, String.class).then()
                    .callParam().fromAttribute("machine").ofIndex(0);

            forPattern("roles/role").callParam().fromAttribute("name")
                    .ofIndex(1);

            forPattern("roles/role").setNext("add");

        }
    });

    Digester digester = DigesterLoader.newLoader(loader).newDigester();
    List<Role> roles = new ArrayList<>();

    digester.push(roles);

    digester.parse(new File("c:/RoleMapping.xml"));

    System.out.println(roles);
    System.out.println(Role.count);

我知道这个问题已经3年了,但我最近遇到了同样的事情,答案仍然有效

构造函数被调用两次的原因是Digester 3使用参数处理构造函数的方式。消化器的问题是鸡和蛋。。。在拥有所有必需参数之前,它无法调用构造函数,但由于
callParam
规则可以从子元素获取其数据,因此在完全处理该元素之前,它不会拥有所有子元素

在您的情况下,所有的参数都在属性中可用,但是如果您将XML更改为:

,请考虑。
<roles>
    <role>
        <name>m1</name>
        <machine>mymachine</machine>
    </role>
</roles>
对于更复杂的情况,或者如果您喜欢这种方法,可以使用生成器类和自定义规则。基本思想是,当您到达元素时,将一个构建器类推送到堆栈上,并在元素结束标记上触发一个自定义规则。在处理元素体时,digester调用所有规则,作为向builder类传递数据的正常方式。在结束标记处,将触发自定义规则,该规则调用构建器来构建对象,然后将摘要堆栈上的构建器对象替换为构建的对象。这确实需要一个自定义生成器类,但比听起来简单得多。有关工作示例,请参见


希望这能解开谜团

我在digester 3.2中也注意到了这种行为,当时我试图解决对象构造函数仅以null作为参数调用的一些问题。你有没有发现打两次电话是否正常?您的构造函数调用时使用了错误的参数,您是否遇到过任何问题?
public class Role {

    private String machine;
    private String name;

    static int count = 0;

    public Role(String machine, String name)  {
        this.machine = machine;
        this.name = name;
        count++;
    }
}
<roles>
    <role>
        <name>m1</name>
        <machine>mymachine</machine>
    </role>
</roles>
<roles>
    <role>
        <name>m1</name>
        <machine>mymachine</machine>
        <another>
            <tag>which</tag>
            <does>morestuff</does>
            ...
        </another>
    </role>
</roles>
forPattern("roles/role").createObject().ofType(Role.class)
    .usingConstructor(String.class, String.class).then()
    .usingDefaultConstructorArguments("one", "two").then()
    .callParam().fromAttribute("machine").ofIndex(0);