Вопрос по enums, generics, managed-bean, java, jsf – Как создать и использовать универсальный компонент для перечислений в f: selectItems?

3

У меня есть общий класс с этой подписью:

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}" />

Мне интересно, действительно ли нужно объявлять производный бин, но не могу получить доступ к универсальному классу как к бину напрямую:

<f:selectItems value="#{enumListBean<Item.Rarity>.enumList}" var="rarity"
                itemLabel="#{rarity.readableName}" itemValue="#{rarity}" />
@BalsusC: О, я только что увидел первый пример. Вы можете опубликовать это как ответ? Sebastian Hoffmann
Вы можете найтиOmniFaces <o:importConstants> полезно. BalusC
@BalusC Ух ты, почти то, чего я хочу достичь. Может<o:importConstants> импортируемый enum может использоваться как список вместе с<f:selectItems>? Sebastian Hoffmann
Проверьте пример витрины. BalusC
В вашем конкретном случае это, вероятно, не будет полезным, даже если EL сможет получить доступ к конкретному параметризованному типу. Там нет никакого способа дляnew EnumListBean<Item.Rarity>.getEnumList() вернуть что-то еще, чемnew EnumListBean<SomethingElse>.getEnumList() без передачи токена типа из-за стирания типа. То, что вы могли бы сделать, это подделать индексированное свойство и иметь компонент, индексируемыйClass это возвращает список его значений, но я не уверен, можете ли вы использовать литералы класса в EL. millimoose

Ваш Ответ

2   ответа
4

основанный на рефлексии. Вы знаете, дженерики доступны только во время компиляции, а не во время выполнения.

Для вашей конкретной цели его, вероятно, легче использоватьOmniFaces <o:importConstants>.

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

(the var attribute is not mandatory, but you'd otherwise need to reference it as #{Item$Rarity} which is not exactly nicely readable; if your Rarity enum were a standalone enum and not an inner enum, then you could just use type="com.example.Rarity")

Это по конструкции рассматривается какMap<String, Rarity>неList<Rarity> или так. Так что, если вы намереваетесь получить доступ к отдельным элементам вvar атрибут<f:selectItems>, так что вы можете получить доступ к определенным методам перечисления, тогда вам нужно явно перебратьMap#values() (что потребует поддержки EL 2.2).

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

ты должен. Потому что создание абстрактных классов не имеет смысла.

Класс является просто абстрактным в текущем случае использования. Я свободен изменить объявление. Sebastian Hoffmann

Похожие вопросы