2014-02-05 45 views
0

我有以下類別:「無法解析匹配構造函數」傳遞時錯誤構造帶參數的子類

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) 

看到錯誤,我嘗試加載g不同的屬性,但沒有運氣。我結束了這樣的事情:

<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有麻煩調用繼承構造函數來實例化類?我能做些什麼來完成這項工作?

回答

5

calling an inherited constructor to instantiate the class?

構造函數永遠不會被繼承,它沒有任何意義。構造函數只是初始化該特定類中的狀態。您不能指望Parent的構造函數初始化Child類的狀態。這只是Child類中構造函數的作用。

所以,不,你不能做你想做的事情。這不是Spring的問題。這非常重要。

+1

它不像你發出聲音那麼明顯。我們假設所有的方法都是通過從類繼承而來的,而構造函數定義在技術上是一種方法,所以我可以看到怎麼會認爲有可能繼承構造函數方法。 –

+0

@MohammadS。嗯。是啊,你說得對。刪除了我的答案的那部分。 –

+0

你在說什麼是有道理的。有一次,我只在父類中留下了默認的構造函數,而在子類中沒有任何內容,並且它拋出了異常。我想這是因爲默認構造函數暗含超級調用(除非我也誤解了這一點)。這只是讓我覺得其他的也被繼承了。 – dnc253

2

簡答:構造函數不是用Java繼承的。

JLS

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

這意味着你必須申報所需要的每個子類的構造函數,並調用相應的超級構造函數。即使它具有相同的簽名,它也不算作重寫。

0

如果你不提供你的孩子類的構造函數,編譯器插入一個無參數的構造函數,並把第一行調用超無參數的構造 所以,你的代碼變爲: -

public class ChildClass extends ParentClass { 

     public ChildClass() { 
      super(); 
     } 
    } 

顯然,U紛紛拋出一個空指針異常可導致的疑難問題。建議你添加一個構造,使超constrcutor一個調用帶String參數: -

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

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

這應該解決所有的問題...

注意: - 如果您添加參數構造函數,編譯器不會爲您添加默認構造函數。

現在,您的bean將正確初始化,因爲它將調用字符串參數構造函數。目前編譯器正在爲你提供一個默認的無參數構造函數,然後調用你的無參數父類構造函數,並拋出一個空指針異常..