2012-02-09 3 views
1

Как заменить методы существующего класса Java (GrailsDataBinder в моем случае). Я читал, что метод вызывает классы java, не проходит через invokeMethod, и, следовательно, он не работает, но я думаю, что будет какое-то решение.Groovy - Как заменить методы существующих классов Java

Я просто попытался это

GrailsDataBinder.metaClass.static.createBinder = {Object target, String objectName -> 
    throw new RuntimeException() 
} 

И это

GrailsDataBinder.class.metaClass.static.createBinder = {Object target, String 
    objectName -> throw new RuntimeException() 
} 

Но это, похоже, не заменил метод, так как мое замыкание не вызываются, но вместо этого оригинального метода выполняется ,

обновление

Я только что узнал, что замыкание выполняется, если я называю createBinder от самого тестового класса - так он работает и метод замены

void testDataBinder() { 
    GrailsDataBinder.createBinder(null, null) 
} 

Однако при вызове из DataBindingUtils он всегда выполняет оригинальный метод (DataBindingUtils также является классом java)

Ниже приведен код внутри DataBindingUtils, который вызывает этот метод.

binder = GrailsDataBinder.createBinder(object, object.getClass().getName()); 

Примечание: Есть некоторые подобные вопросы, заданные ранее, но ни один из них не работал для меня.

+0

Является ли вызов вызова DataBindingUtils из Groovy? Время выполнения Groovy требуется для изменения метакласса. Если вы интегрируете Groovy в Java и вызов выполняется с Java, тогда он не увидит исправленные изменения. –

+0

Да, вызов DataBindingUtils осуществляется через BindDynamicMethod, который вызвал вызов из классного класса. И я попытался вызвать DataBindingUtils непосредственно из случая с блоками тестов Grails. –

ответ

1

Это разочаровывает, как только вы увидите мощь Groovy. Однако, как вы уже знаете, многие классные метаклассы и т. Д., Доступные в Groovy, просто не работают так, как вы хотели бы на Java-классах.

Если вы пытаетесь переопределить, заглушить или издеваться над классом Java для модульного тестирования и т. Д., Я советую искать Spock, потому что он использует «магию», которая также работает и на Java-классах.

Если вы пытаетесь переопределить методы по какой-либо другой причине, попробуйте расширить класс Java классом Groovy или «обернуть» класс Java классом Groovy, чтобы получить функции метакласса, которые вы хотите, когда внешние классы звонят вам классов. К сожалению, это все равно не позволит вам перехватывать вызовы, которые класс Java делает для себя.

Смежные вопросы