Groovy способ создания интерфейса во время выполнения? - PullRequest
1 голос
/ 16 марта 2020

Цель: создать экземпляр интерфейса во время выполнения, а затем обработать любой вызов на нем. Под «любым» я подразумеваю, что даже вызовы методов не были определены непосредственно в интерфейсе.

Дизайн: я приводю Map к нужному типу, а затем добавляю некоторые методы к его metaClass .

Результат: это существо может успешно обрабатывать необъявленные методы, но не может обрабатывать честно объявленные - выдается исключение UnsupportedOperationException.

Вопрос: можно ли обрабатывать также объявленные методы?

interface StackApi {
    void declaredMethod()
}

@Test
void reproduction() {
    StackApi api = [:].asType(StackApi)
    api.metaClass.declaredMethod = { Object[] args -> println "declaredMethod!"}
    api.metaClass.undeclaredMethod = { Object[] args -> println "undeclaredMethod!"}
    api.undeclaredMethod() // invoked ok
    api.declaredMethod() // UnsupportedOperationException thrown
}

UPD. Мне удалось исправить это частично (см. Ниже), но это работает только для предварительно известных имен методов. Может быть, есть способ настроить один обработчик, который принимает абсолютно все вызовы?

@Test
void partial_success() {
    StackApi api = [
            declaredMethod: { Object[] args -> println "declaredMethod!"},
    ].asType(StackApi)
    api.metaClass.undeclaredMethod = { Object[] args -> println "undeclaredMethod!"}
    api.undeclaredMethod() // ok
    api.declaredMethod() // ok
}

PS приведение к StackApi важно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...