Рефлексивно создайте анонимный класс - PullRequest
0 голосов
/ 12 декабря 2018

Я намереваюсь импортировать библиотеку (jar), используя мой собственный ClassLoader, и выясняется, что необходимо установить прослушиватель для одного из классов, например,

Class<?> clazz = getInitializerClass();
Object initializer = clazz.newInstance();

// I would like the below listener to be set on this initializer reflectively
// setOnInitListener() is mathod to be called on initializer
setOnInitListener(new OnInitCompleteListener(){
    @Override
    public void onInit(){
    }
}

Проблема в том, что яу меня нет прослушивателя, доступного в качестве импорта, и все, что я могу получить - это динамически OnInitCompleteListener.class путем загрузки классов на лету.

Как мне добиться вышеупомянутого?

Примечание: Я готов пойти на все, чтобы достичь того же, но был бы признателен за простой подход.

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Анонимные классы являются артефактами времени компиляции.У них даже есть имена, по которым Java-компилятор может их идентифицировать, хотя они и недоступны для программистов.

Однако есть обходной путь: поскольку OnInitCompleteListener - это интерфейс, вы можете создать динамический прокси, реализующий ваш интерфейс.:

InvocationHandler handler = new InvocationHandler() {
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("onInit")) {
            ... // Listener's code goes here
        }
    }
};
Class<T> onInitCompleteListenerClass = ... // You get this one dynamically
Object listener = Proxy.newProxyInstance(
    classLoader,
    new Class[] { onInitCompleteListenerClass },
    handler);
// Use listener in the reflective call to a method taking OnInitCompleteListener

MyInvocationHandler реализует интерфейс InvocationHandler.Его invoke метод может обнаружить, что он вызывается вместо onInit, и выполнять работу по мере необходимости.

0 голосов
/ 12 декабря 2018

Предполагая, что ваш класс OnInitCompleteListener доступен в том же загрузчике классов, в котором вы выполняете остальную часть этого кода в ...

Вы можете получить метод setOnInitListener с отражением против экземпляра класса:

Method setter = clazz.getDeclaredMethod("setOnInitListener", OnInitCompleteListener.class);
setter.invoke(initializer, new OnInitCompleteListener() {
    @Override
    public void onInit()  {
        // implementation
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...