Цель: создать экземпляр интерфейса во время выполнения, а затем обработать любой вызов на нем. Под «любым» я подразумеваю, что даже вызовы методов не были определены непосредственно в интерфейсе.
Дизайн: я приводю 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
важно