2013-10-15 17 views
2

我有一個泛型類:方法重載不能像使用Java泛型預計

public class Facet<C extends Component> 
{ 
    private final C child; 

    public Facet(C child) { this.child = child; } 

    public C getChild() { return this.child; } 

    public UIComponent getViewComponent() { 
     return PrimeFacesComponentFactory.create(facesContext, this.getChild()); 
    } 
} 

我有一個組件工廠,也有一堆的方法,其中有幾個是這樣的:

public static UIComponent create(FacesContext fc, Component component) { 
    throw new UnsupportedOperationException("Method not yet implemented for class: " + component.getClass().getName()); 
} 

public static UIRow create(FacesContext fc, Row modelRow) { ... } 

public static UIColumn create(FacesContext fc, Column modelColumn) { ... } 

NOTE:在每個工廠方法中,第二個參數是一個擴展Component的對象,返回的對象始終是UIComponent的一個子類。第一個工廠方法(引發異常的方法)是「catch all」,如果沒有爲特定組件編寫特定的工廠方法,則會調用該方法。

我在做什麼:正確的工廠方法應根據組件facet的子類型是什麼類型來調用。發生什麼事是第一種工廠方法是總是調用(例如引發異常的方法)。這對我來說是違反直覺的,因爲C的類型在運行時是已知的,C是「擴展Component的某種特定類型」。

調試,我在Facet#getViewComponent設置斷點,調用它,當我知道facet.getChild()將返回類型行的對象。所以在這個例子中C是Row。令我驚訝的是,當工廠方法被調用時,例如

PrimeFacesComponentFactory.create(facesContext, facet.getChild()); 

程序執行流向「catch all」工廠方法!但是,如果我明確投facet.getChild()如下:

PrimeFacesComponentFactory.create(facesContext, (Row)facet.getChild()); 

然後調用特定的方法。奇怪,因爲我簡單地/冗餘地將一行放到一行。

我讀過some about why this is happening,但它仍然朦朧和違反我的想法。無論如何,我該如何解決這個問題?

+0

你可以在調用'create(..)'之前顯示'facet'聲明嗎?或者你的意思是'this.getChild()'? –

+0

哦,對!我做了很多代碼簡化操作,讓示例更直接,而且,不是'facet.getChild()',而應該簡單地按照您的建議使用'this.getChild()'。我會更新這個問題。 –

回答

3

中的重載決策發生一次,在編譯時,爲Facet類,而不是在每個Facet<C>C,而不是在運行時。一個潛在的解決方案是讓你的包羅萬象的方法更聰明:

public static UIComponent create(FacesContext fc, Component component) { 
    if (component instanceof Row) 
     return create(fc, (Row)component); 
    else if (component instanceof Column) 
     return create(fc, (Column)component); 
    // include other types, and lastly 
    else 
     throw new UnsupportedOperationException("Method not yet implemented for class: " + component.getClass().getName()); 
} 
+0

好主意。然而,我希望沒有那麼多if-else-if,因爲有這麼多的組件。也許使用訪問者... –

+1

訪問者的優勢是少(在0)投,但肯定不少行。 –

+0

@JudgeMental如果我使用訪問者,那麼我將能夠從「catch all」方法中刪除所有if/else-ifs,這將會減少行數。 –

0

用下面的聲明

public C getChild() { return this.child; } 

public UIComponent getViewComponent() { 
    return PrimeFacesComponentFactory.create(facesContext, facet.getChild()); 
} 

假設facet,就是要this,在編譯的時候,是已知的唯一的事情類型參數C是它延伸Component。因此,編譯器將此方法調用與聲明爲接受Component的方法綁定。

public static UIComponent create(FacesContext fc, Component component) { 
    throw new UnsupportedOperationException("Method not yet implemented for class: " + component.getClass().getName()); 
} 
+0

謝謝我更新了這個問題。 'facet.getChild()'不正確。它應該是'this.child'。 –

+0

@PatrickGarner對。所以這就是它發生的原因。至於解決方案,請查看Tim的。我可能會嘗試一些,但現在沒時間了。 –