Java: Динамическое преобразование типа с помощью перечислений

Я пытаюсь сделать что-то вроде:

public void setContents(Object[] values)
{
    ...

        //A. this works
        mRank =
            ((String)(values[Columns.RANK.index])); 

        //B. doesn't work (entire line underlined by netbeans)
        mRank =
            (Columns.RANK.type.cast(values[Columns.RANK.index]));
        //incompatible types: required java,lang.String found: java.lang.Object

        //C. doesn't work (first RANK is underlined by netbeans)
        mRank =
            ((Columns.RANK.type)(values[Columns.RANK.index]));
        //cannot find symbol symbol: class RANK location: blah.blah.Columns

    ...
}

Где столбцы являются внутренним перечислением, как так:

public static enum Columns
{

    RANK(0, "Rank", String.class),
    NUMBER(1, "Number", Integer.class);

    public String text;
    public Class type;
    public int index;

    private Columns(int idx, String text, Class clasz)
    {
        this.type = clasz;
        this.text = text;
        this.index = idx;
    }
}

Я понимаю почему строка B не работает, но что я не получаю, то, почему C не работает. Если я использую Columns.RANK.type где-либо еще кроме в броске типа, это хорошо работает, но один я пытаюсь сделать преобразование типа с классом, это компилирует высказывание, что это не может найти RANK в перечислении, которое не должно иметь место.

Как работать вокруг?

Спасибо!

6
задан bguiz 22 January 2010 в 01:20
поделиться

3 ответа

C не работает, потому что Columns.rank.Type не доступен при компиляционном времени.

Однако B B могут быть реализованы с использованием пользовательского универсального класса вместо enum :

class Columns<T>
{
    public static final Columns<String> RANK = new Columns<String>(0, "Rank", String.class);
    public static final Columns<Integer> NUMBER = new Columns<Integer>(1, "Number", Integer.class);

    public final Class<T> type;
    public final String text; 
    public final int index; 

    private Columns(int idx, String text, Class<T> clasz) 
    { 
        this.type = clasz; 
        this.text = text; 
        this.index = idx; 
    } 
}
4
ответ дан 17 December 2019 в 02:28
поделиться

Как оно ссылается на буквальный литерал , выражение Columns.rank.type имеет тип класс Отказ Это не реферат , требуемый литой выражением .

Дополнение: Компилятор считает, что вы имели в виду, чтобы ссылаться на несуществующий класс с именем , который вложен в колоннах .

0
ответ дан 17 December 2019 в 02:28
поделиться

Короткий ответ: нет хорошего способа сделать это с помощью перечисления. Ответ axtavt, вероятно, ваш лучший выбор. trashgod в основном прав в отношении того, почему C не работает, но, возможно, для него нужно немного больше объяснений.

Вам нужно подумать о том, как компилятор интерпретирует C . Здесь важно различие между String и String.class . У вас есть выражение приведения типа (String) foo .В таком выражении тип, к которому вы приводите (в этом примере, String ), должен быть именем типа. Вы бы не стали писать (String.class) foo , потому что не существует класса с именем String.class . (Вместо этого String.class - это просто объект, экземпляр java.lang.Class , который отражает тип String .)

Итак, когда компилятор видит (Columns.RANK.type) (values ​​[Columns.RANK.index]) , он говорит: «ах, это выражение приведения. Итак, бит в скобках в начале должен быть имя типа, к которому bguiz хочет привести ". Затем он послушно отключается и ищет тип с именем Columns.RANK.type . Поскольку это имя типа, ожидается, что оно будет иметь форму my.package.contain.a.Type.AndMaybe.SomeInnerTypes . Таким образом, он разбивает его вокруг . s, находит тип Columns , а затем уходит и ищет внутренний тип с именем RANK в Columns . Такого внутреннего типа нет (константа RANK не учитывается), поэтому он не работает с указанной вами ошибкой.

(Если бы он обнаружил это, он продолжил бы поиск другого внутреннего типа с именем type , и опять же, поле в перечислении не будет учитываться.)

Помните, что компилятор просто следует куча тупых правил. Неважно, что у вас также есть постоянная RANK в вашем перечислении Columns . Он также не знает, что имена типов обычно пишутся в верхнем регистре.В результате его сообщения об ошибках иногда трудно интерпретировать для человека, который носит весь этот контекст в своей голове. :)

2
ответ дан 17 December 2019 в 02:28
поделиться
Другие вопросы по тегам:

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