Java Прокси выдает исключение NullPointerException - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь зарегистрировать ClickListener для кнопки. Я использую Vaadin 8. Этот слушатель должен быть реализован с использованием Proxy.

final Button button = new Button("Hello");

final Class<?> clickListenerClass = Button.ClickListener.class;
final Object clickListenerInstance = Proxy.newProxyInstance(clickListenerClass.getClassLoader(),
    new Class[] {clickListenerClass}, (proxy, method, args) -> {
        System.out.println("TEST");

        return null;
    });

button.addClickListener((Button.ClickListener)clickListenerInstance);

Вот трассировка стека (я пропустил свой код. Исключение происходит в последней строке приведенного выше фрагмента).

java.lang.NullPointerException: null
    at com.sun.proxy.$Proxy20.hashCode(Unknown Source)
    at com.vaadin.event.ListenerMethod.hashCode(ListenerMethod.java:571)
    at java.util.HashMap.hash(HashMap.java:339)
    at java.util.HashMap.put(HashMap.java:612)
    at java.util.HashSet.add(HashSet.java:220)
    at com.vaadin.event.EventRouter.addListener(EventRouter.java:64)
    at com.vaadin.server.AbstractClientConnector.addListener(AbstractClientConnector.java:842)
    at com.vaadin.ui.Button.addClickListener(Button.java:333)

1 Ответ

3 голосов
/ 19 июня 2020

Вы возвращаете null для любого вызова метода на прокси. В трассировке стека вы можете видеть, что Ваадин вызывает метод hashCode, который возвращает null в соответствии с вашей реализацией. Из документации InvocationHandler Javadocs метод invoke возвращает:

значение, возвращаемое при вызове метода в экземпляре прокси. Если объявленный тип возврата метода интерфейса является примитивным типом, тогда значение, возвращаемое этим методом, должно быть экземпляром соответствующего примитивного класса-оболочки; в противном случае это должен быть тип, присваиваемый объявленному возвращаемому типу. Если значение, возвращаемое этим методом, равно null, а тип возвращаемого значения интерфейса - примитивный, то при вызове метода в экземпляре прокси будет выброшено исключение NullPointerException. Если значение, возвращаемое этим методом, в противном случае несовместимо с объявленным типом возврата метода интерфейса, как описано выше, при вызове метода в экземпляре прокси будет выброшено исключение ClassCastException.

Так, например, вы вам понадобится ссылка на целевой объект, вызовите из него метод и верните результат. Есть хороший учебник по адресу https://www.baeldung.com/java-dynamic-proxies

...