【发布时间】:2013-10-16 02:34:27
【问题描述】:
我有一个通用类:
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) { ... }
注意:在每个工厂方法中,第二个参数是扩展 Component 的对象,返回的始终是 UIComponent 的子类。第一个工厂方法(引发异常的那个)旨在成为“包罗万象”,如果没有为特定组件编写特定的工厂方法,则会调用它。
我正在尝试做的事情:应该调用正确的工厂方法,具体取决于组件方面的子组件类型。发生的事情是第一个工厂方法总是被调用(例如,抛出异常的那个)。这对我来说是违反直觉的,因为 C 的类型在运行时是已知的,而 C 是“扩展组件的某种特定类型”。
调试,我在Facet#getViewComponent设置了一个断点,当我知道facet.getChild()会返回一个Row类型的对象时调用它。所以在这个例子中,C 是 Row。让我惊讶的是,当调用工厂方法时,例如
PrimeFacesComponentFactory.create(facesContext, facet.getChild());
程序执行流向“catch all”工厂方法!但是,如果我显式转换 facet.getChild() 如下:
PrimeFacesComponentFactory.create(facesContext, (Row)facet.getChild());
然后调用特定的方法。很奇怪,因为我只是/冗余地将一行转换为一行。
我读过some about why this is happening,但对我来说它仍然很模糊且违反直觉。无论如何,我该如何解决这个问题?
【问题讨论】:
-
你能在调用
create(..)之前显示facet的声明吗?还是您的意思是this.getChild()? -
哦,对了!我做了很多代码简化以使示例更简单,是的,而不是
facet.getChild()它应该只是this.getChild()正如你所建议的那样。我会更新问题。