Как можно поступить с общими перечислениями в Java? - PullRequest
2 голосов
/ 03 июля 2010

Итак, у меня есть абстрактный класс, такой как:

public abstract class AbstractParent <E extends Enum<E>> {...}

Где-то в неабстрактном методе внутри AbstractParent, я хотел бы перебрать значения E. Возможно ли это?

Для лучшего примера:

public abstract class AbstractParent <E extends Enum<E>> {
    ...
    protected void doSomething() {
        //iterate over the values of E and perform an action using them
    }
}

public class Child extends AbstractParent<Child.Index> {
    public static enum Index {
        ...
    }
    public Child() {
        super();
        this.doSomething(); //this should iterate over Index's values
    }
}

РЕДАКТИРОВАТЬ:

Итак, благодаря mdma, это работает потрясающе:

public abstract class AbstractParent <E extends Enum<E>> {
    ...
    protected void doSomething() {
        //iterate over the values of E and perform an action using them
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        Type t = pt.getActualTypeArguments()[0];
        E[] enumValues = ((Class<E>)t).getEnumConstants();
        // enumValues is now an iterable array of the values inside Index
    }
}

public class Child extends AbstractParent<Child.Index> {
    public static enum Index {
        ...
    }
    public Child() {
        super();
        this.doSomething(); //this should iterate over Index's values
    }
}

Спасибо ЗАГРУЗКИ на mdma, вы заслуживаетебольше очков, чем я могу дать.

Ответы [ 2 ]

5 голосов
/ 03 июля 2010

EDIT2: Обобщения на суперклассах и интерфейсах не стираются. Вы можете получить универсальный тип во время выполнения и использовать его для получения значений перечисления. Смотрите Class.getGenericSuperclass. Это избавит вас от необходимости передавать значение или класс в конструкторе.

Оригинал: Вы не можете сделать это с генериками. Однако, если вы переходите в соответствующий класс, например, конструктор типа

AbstractParent(Class<E> enumClass)
{
   this.enumClass = enumClass;
}

Затем вы можете использовать это для получения соответствующих значений перечисления через

public E[] getValues()
{
    return this.enumClass.getEnumConstants();
}

РЕДАКТИРОВАТЬ: Хотя клиенты не являются профессиональными программистами, компилятор будет гарантировать, что правильный класс передается. Вы также можете прояснить использование, предоставив примеры и модульные тесты.

Вы также можете получить конструктор и реальное значение Enum и извлечь класс из этого. Это может быть проще в использовании, так как параметр тогда будет E, а не более "страшным" Class<E>.

Е.Г.

AbstractParent(E enumValue)
{
   this.enumClass = enumValue.getClass();
}
2 голосов
/ 03 июля 2010

Поскольку обобщения стираются во время выполнения, единственный возможный способ это сделать - это иметь конструктор, который требует параметр Class<E>, для которого вы затем можете вызвать getEnumConstants().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...