Я хотел бы повторно реализовать метод класса Java. Например, для «hi» .length ()
вернуть 4
. (Как мне это сделать?
Я знаю, что с помощью SomeClass.metaClass я могу получить ссылку на существующий метод и определить новый (или переопределяющий) метод, но я не могу сделать это для существующих методов Java.
Кажется, это возможно, если злоупотреблять String metaClass . Но попытка, которую я сделал до сих пор в groovy console, не привела к ожидаемому результату :
def oldLength = String.metaClass.length
String.metaClass.length = { ->
return oldLength+10;
}
println "hi".length()
выводит грустный 2
Думаю, вы могли бы взглянуть на Proxy MetaClass или Delegating metaClass.
Если вы его переопределите, он будет работать только в коде Groovy. Groovy не может изменить способ выполнения кода Java.
В Groovy "hi" .length ()
примерно эквивалентно этой Java:
stringMetaClass.invokeMethod("hi","length");
Поскольку Groovy на самом деле не вызывает длину напрямую, уловки с метаклассами работают в коде Groovy. Но Java не знает о MetaClasses, поэтому нет никакого способа заставить это работать.
Используя Groovy, вы можете заменить любой метод (даже методы конечных классов) своей собственной реализацией. Замена метода в Groovy использует протокол метаобъектов, а не наследование.
Вот запрошенный вами пример, например, как заставить String.length ()
всегда возвращать 4
// Redefine the method
String.metaClass.invokeMethod = { name, args ->
def metaMethod = delegate.metaClass.getMetaMethod(name, args)
def result = metaMethod.invoke(delegate, args)
name == 'length' ? 4 : result
}
// Test it
assert "i_do_not_have_4_chars".length() == 4