2012-07-17 78 views
3

我有通用类与此签名:如何在f:selectItems中为枚举创建和使用泛型bean?

public abstract class EnumListBean<E extends Enum<E>> { 

    public List<E> getEnumList() { 
     //implementation details 
    } 

} 

目前我有才能访问enumList属性的具体泛型参数来定义一个空的子类:

@ManagedBean 
@ApplicationScoped 
public class ItemRarityBean extends EnumListBean<Item.Rarity>{ 
} 

这使得它能够访问属性例如:

<f:selectItems value="#{itemRarityBean.enumList}" var="rarity" 
      itemLabel="#{rarity.readableName}" itemValue="#{rarity}" /> 

我想知道是否真的必须声明一个派生bean,但无法访问吨他通用类直接作为bean:

<f:selectItems value="#{enumListBean<Item.Rarity>.enumList}" var="rarity" 
       itemLabel="#{rarity.readableName}" itemValue="#{rarity}" /> 
+0

你会发现[OmniFaces'<○:importConstants>'](https://showcase-omnifaces.rhcloud.com/showcase/taghandlers/importConstants.xhtml)是有用的。 – BalusC 2012-07-17 19:03:52

+0

在您的具体情况下,即使EL可以访问具体的参数化类型,它也可能不会有用。由于类型擦除,'new EnumListBean .getEnumList()'不返回除'new EnumListBean .getEnumList()'以外的任何内容,而不传递类型标记。你可以做的是伪造一个索引属性,并且有一个可以通过'Class'索引的bean,该类返回它的值列表,但我不确定是否可以在EL中使用类文字。 – millimoose 2012-07-17 19:07:30

+0

@BalusC哇,几乎是我想要达到的确切的东西。一个''输入的枚举是否可以和''一起用作列表? – Paranaix 2012-07-17 19:12:13

回答

4

您不能在EL中使用泛型。 EL是基于反射的运行时语言。你知道,泛型只在编译期间可用,而不是在运行期间。

为了您的特定目的,它可能更易于使用OmniFaces<o:importConstants>

<o:importConstants type="com.example.Item$Rarity" var="Rarity" /> 
... 
<h:selectOneMenu> 
    <f:selectItems value="#{Rarity}" /> 
</h:selectOneMenu> 

(该var属性不是强制性的,但否则你需要引用它作为#{Item$Rarity}这不正是很好的可读性;如果你Rarity枚举是一个独立的枚举,而不是内部枚举,那么你可以使用type="com.example.Rarity"

它在设计上被当作Map<String, Rarity>而不是List<Rarity>左右。因此,如果您打算访问属性<f:selectItems>中的单个项目,以便您可以访问特定的枚举方法,那么您需要明确地重复执行Map#values()(这将需要EL 2.2支持)。

<h:selectOneMenu> 
    <f:selectItems value="#{Rarity.values()}" var="rarity" itemValue="#{rarity}" itemLabel="#{rarity.readableName}" /> 
</h:selectOneMenu> 
2

是的,你必须。因为实例化抽象类是没有意义的。

+1

这个类在当前用例中只是抽象的。我可以自由改变宣言。 – Paranaix 2012-07-17 19:06:43