Как я могу получить доступ к методам, основанным на строках в массиве?
Здравствуйте!
Я даже не уверен, возможно ли это, но, надеюсь, это на Java. Я знаю, что сделал это в PHP, используя переменные переменные и динамический доступ к переменной, но я прочитал, что это невозможно в Java по другому вопросу.
У меня есть массив строк, который содержит состояние флажков в моем графическом интерфейсе JSF. Если установлены все флажки, массив будет заполнен строками, содержащими значения различных флажков.
Метки и значения флажков строятся путем циклического перебора массива, который выглядит следующим образом:
private static final String[][] OVERVIEW_FIELDS = {{"ID", "requestid"},
{"Date added", "dob"}, {"Title", "requestTitle"}, {"Process", "processId"},
..., ..., ...};
Затем я перебираю массив и делаю из него JSF SelectItems:
for (int i = 0; i < OVERVIEW_FIELDS.length; i++) {
SelectItem item = new SelectItem(OVERVIEW_FIELDS[i][0], OVERVIEW_FIELDS[i][1]);
getFields().add(item);
}
Проблема и текущее решение (надеюсь, кто-то может помочь мне преобразовать ее в нечто лучшее:
for (String item : getVisibleFields()) {
if (item.equals("dob")) {
setDob(true);
}
if (item.equals("requestTitle")) {
setRequestTitle(true);
}
if (item.equals("processId")) {
setProcessId(true);
}
if (...) {
}
}
И так далее для 11 логических значений. Мне не нравится это решение, и я вижу похожие шаблоны в других компонентах в моей системе.
Кто-нибудь знает, есть ли лучшее решение для этого? Логические столбцы управления, где я устанавливаю их отображаемое поле в true/false в соответствии с тем, что содержится в массиве флажков.
Я надеялся, что в JSF EL я смогу получить доступ к переменной visibleFields и методу contains, таким образом возвращая либо true, либо false, если объект существует в массиве. Это, похоже, не работает, и EL не дает мне доступ к методу содержимого.
В настоящее время я использую:
rendered="#{overviewFilterBean.dob}"
И я попробовал с этим кодом:
rendered="#{overviewFilterBean.visibleFields.contains['dob']}">
Теперь это заставило меня попытаться использовать мой окончательный массив и установить логические значения в соответствии с getFields().contains(OVERVIEW_FIELDS[i][1])
, но как я могу сделать это возможным?
Далее следует реальный и псевдокод (решение, к которому я стремился):
for (int i = 0; i < OVERVIEW_FIELDS.length; i++) {
if (item.equals(OVERVIEW_FIELDS[i][1])) {
setOVERVIEW_FIELDS[i][1](true);
}
}
Большой вопрос:
Есть ли способ для меня использовать значение из OVERVIEW_FIELDS[i][1]
установить правильную логическую переменную или я могу превратить это в карту, возможно, и использовать EL JSF, чтобы проверить, существует ли ключ на карте?
Спасибо за ваше время, и извините за написание такого длинного вопроса, чтобы добраться до небольшой точки:/
РЕДАКТИРОВАТЬ:
Метод отражения привел к 5 исключениям, большой блок кода обрабатывает их, а также люди говорят, что это дорогой метод. Это заставляет меня верить, что либо мое старое решение, либо использование карт - лучший способ сделать это. Я собираюсь попробовать решение карты =)
3 ответа
Вы всегда можете хранить значения на карте. Однако, если вы хотите вызывать методы, основанные на имени метода в виде строки, используйте отражение. См. http://java.sun.com/developer/technicalArticles/ALT/Reflection/
С отражением вы можете сделать:
for (String item : getVisibleFields()) {
getClass().getMethod("get" + capitalize(item)).invoke(this, true);
}
Обработка исключений и capitalize
метод оставлен в качестве упражнения для читателя (invoke
кидает много исключений).
Вы можете использовать API отражения Java для динамического поиска поля и его установки, как в этом примере. Обратите внимание, что у этого метода будет снижение производительности.