Я пытаюсь сделать что-то вроде:
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
в перечислении, которое не должно иметь место.
Как работать вокруг?
Спасибо!
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;
}
}
Как оно ссылается на буквальный литерал , выражение Columns.rank.type
имеет тип класс
Отказ Это не реферат , требуемый литой выражением .
Дополнение: Компилятор считает, что вы имели в виду, чтобы ссылаться на несуществующий класс с именем
, который вложен в колоннах
.
Короткий ответ: нет хорошего способа сделать это с помощью перечисления. Ответ 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
. Он также не знает, что имена типов обычно пишутся в верхнем регистре.В результате его сообщения об ошибках иногда трудно интерпретировать для человека, который носит весь этот контекст в своей голове. :)