传递给子类的constructor-arg时“无法解析匹配的构造函数”错误

时间:2014-02-05 16:51:59

标签: java spring inheritance constructor

我有以下课程:

public abstract class ParentClass
{
    public ParentClass()
    {
        throw new RuntimeException("An ID must be specified.");
    }

    public ParentClass(String id)
    {
        this(id, DEFUALT_ARG_VALUE);
    }

    public ParentClass(String id, int anotherArg)
    {
        this.id = id;
        //stuff with anotherArg
    }

    public abstract void doInstanceStuff();
}

public class ChildClass extends ParentClass
{
    @Override
    public void doInstanceStuff()
    {
        //....
    }
}

在我的应用程序上下文中,我有:

<bean id="myChildInstance" class="com.foo.bar.ChildClass " scope="singleton">
    <constructor-arg value="myId" />
</bean>

问题是,当服务器启动时,我收到以下错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ivpluginHealthCheckTest' defined in ServletContext resource [/WEB-INF/spring/root-context.xml]: Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)

看到错误,我尝试添加不同的属性,但没有运气。我最终得到了类似的东西:

<bean id="myChildInstance" class="com.foo.bar.ChildClass " scope="singleton">
    <constructor-arg value="myId" index="0" type="java.lang.String" name="id" />
</bean>

我仍然得到同样的错误。

我尝试将相同的构造函数添加到我的子类中,然后使用适当的参数调用super(),这似乎可以解决它。但是,我不想在所有子实例中添加相同的构造函数,并且必须使用父类维护它们。

是否有一些原因Spring调用继承的构造函数来实例化该类?我可以做些什么来使这项工作?

3 个答案:

答案 0 :(得分:5)

  

调用继承的构造函数来实例化类?

构造函数永远不会被继承,并且它实际上没有意义。构造函数只是初始化该特定类中的状态。您不能指望Parent的构造函数初始化Child类的状态。这只是Child类中构造函数的作用。

所以,不,你不能做你想做的事。这不是Spring的问题。这是非常基础的。

答案 1 :(得分:2)

简短回答:构造函数不是用Java继承的。

来自JLS

Constructor declarations are not members. They are never inherited and therefore are not subject to hiding or overriding. 

这意味着您必须声明每个子类所需的构造函数并调用相应的超级构造函数。即使它具有相同的签名,也不算是压倒一切。

答案 2 :(得分:0)

如果在子类中没有提供构造函数,编译器会插入一个no-arg构造函数并将第一行添加为对super no-arg构造函数的调用 所以你的代码变成: -

public class ChildClass extends ParentClass {

        public ChildClass() {
            super();
        }
    }

显然,你已经抛出了一个可能导致问题的空指针异常。我建议你添加一个构造函数并调用一个带有String参数的超级构造函数: -

public class ChildClass extends ParentClass {
        public ChildClass(String id) {
            super(id);
        }

        @Override
        public void doInstanceStuff() {
            // ....
        }
    }

这可以解决你所有的问题......

注意: - 如果添加参数构造函数,编译器不会为您添加默认构造函数。

现在你的bean将正确初始化,因为它将调用字符串参数构造函数。目前,编译器为您提供了一个默认的无参数constrcutor,它反过来调用你的无参数父类构造函数,并抛出一个空指针异常..