Как переопределить метод для экземпляра java-типа с помощью метапрограммирования Groovy? - PullRequest
1 голос
/ 27 октября 2010

Я пытаюсь переопределить функциональность метода экземпляра java-типа в моем коде Groovy, но получаю исключение classcast.

Я посмотрел руководство, опубликованное здесь , но не могу заставить его работать.

Поскольку моей настоящей проблемой является небольшая путаница, ниже приведен пример запускаемого кода, который завершается с той же ошибкой. В этом примере я хочу переопределить метод substring экземпляра класса java.lang.String. В действительности я хочу переопределить метод экземпляра класса, который не имеет соответствующей реализации Groovy, поэтому ответом на мой пример является не просто использование экземпляра строки Groovy.

class example {
    static void main(args) {
        java.lang.String hey = new java.lang.String("hey")
        ExpandoMetaClass emc = new ExpandoMetaClass( java.lang.String, false )
            emc.substring = {
                       "This is not a very good substring implementation"
                }
            emc.initialize()

        def proxiedHey = new groovy.util.Proxy().wrap(hey)
        proxiedHey.setMetaClass(emc)
        printf proxiedHey.toString()
        printf proxiedHey.substring(1)
    }
}

Приведенный выше пример завершается с ошибкой в ​​строке 12, то есть printf meh.toString (). Исключение составляет

Поймано: java.lang.ClassCastException: groovy.util.Proxy не может быть приведен к java.lang.CharSequence at example.main (test.groovy: 12)

Итак, есть ли идеи о том, что я делаю неправильно или есть другой способ решить мою проблему добавления и / или переопределения методов экземпляра типа Java?

Я использую Groovy версии 1.7.4.

Ответы [ 2 ]

2 голосов
/ 27 октября 2010

Вы создаете ExpandoMetaClass для java.lang.String, но назначаете его для groovy.util.Proxy.Создайте метакласс для groovy.util.Proxy instread, например:

java.lang.String hey = new java.lang.String("hey")
def proxiedHey = new groovy.util.Proxy().wrap(hey)
ExpandoMetaClass emc = new ExpandoMetaClass( groovy.util.Proxy, false )
emc.substring = {
    "This is not a very good substring implementation"
}
emc.initialize()

proxiedHey.setMetaClass(emc)
printf proxiedHey.toString()
printf proxiedHey.substring(1)
0 голосов
/ 08 января 2015

Вы смотрели на Pimp my Library Pattern , который позволяет добавлять, используя Groovy Categories .В вашем случае это может оказаться более удобным и простым для понимания.

@Category(String)
class StringSubstrCategory {      
    def substring( int n)   { 
        "This is not a very good substring implementation"
    }
}

use (StringSubstrCategory) {
    "hey".substring(1)
}
...