Как вызвать действие JSF для анонимного класса? EL не может получить к нему доступ

Оператор == проверяет, указывают ли две ссылки на один и тот же объект или нет. .equals() проверьте фактическое содержимое строки (значение).

Обратите внимание, что метод .equals() принадлежит классу Object (суперкласс всех классов). Вам необходимо переопределить его в соответствии с вашим требованием к классу, но для String оно уже реализовано и проверяет, имеет ли две строки одно и то же значение.

  • Случай 1
    String s1 = "Stack Overflow";
    String s2 = "Stack Overflow";
    s1 == s2;      //true
    s1.equals(s2); //true
    
    Причина: строка литералы, созданные без нуля, хранятся в пуле строк в области перментонов кучи. Таким образом, оба s1 и s2 указывают на один и тот же объект в пуле.
  • Случай 2
    String s1 = new String("Stack Overflow");
    String s2 = new String("Stack Overflow");
    s1 == s2;      //false
    s1.equals(s2); //true
    
    Причина. Если вы создаете объект String с использованием ключевого слова new, ему выделяется отдельное пространство в куче.
7
задан Lii 25 January 2016 в 12:51
поделиться

1 ответ

Это потому, что анонимные классы недоступны за пределами пакета, содержащего анонимный класс.

Вот демонстрация того, что происходит за кулисами:

public static void main(String[] args) throws Exception {
    Portal portal = new Portal();
    Object list = portal.getClass().getDeclaredMethod("getActionList", null).invoke(portal, null);
    Object action = list.getClass().getDeclaredMethod("get", new Class[] { int.class }).invoke(list, 0);
    action.getClass().getDeclaredMethod("action", null).invoke(action, null);
}

Попробуйте выполнить это в том же пакете, что и Portal класс, а затем еще раз в другом классе вне пакета. В другом пакете последняя строка вызовет точно такое же исключение. Это проблема, с которой борется EL, поскольку она основана на отражении.

Я не вижу других способов решить эту проблему, кроме как просто создать public (внутренний) класс. Reflection (а значит и EL) может получить к ним доступ из других пакетов.

public class Portal {

    private List<IAction> list = new ArrayList<IAction>();

    public Portal() {
        list.add(new IActionImpl());
    }

    public class IActionImpl implements IAction {
        public void action() {
            System.out.println("called action here");
        }
    }

    public List<IAction> getActionList() {
        return list;
    }

}
11
ответ дан 6 December 2019 в 23:01
поделиться
Другие вопросы по тегам:

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