2010-08-23 4 views
7

Я хотел бы повторно реализовать метод класса Java. Например, для "hi".length() для возврата 4. (Как мне это сделать?Могу ли я переопределить длину строки?

Я знаю, используя SomeClass.metaClass Я могу получить ссылку на существующий метод и определить новый (или переопределяющий) метод, но я, похоже, не могу это сделать для существующих методов Java.

+0

Это было бы неправильное поведение. Возможно, вы сможете использовать метод 'pad()', который расширяет вашу строку до заданной максимальной длины. Затем вы можете называть длину этой строки. – Nate

+0

Что вам нравится с этим? Таким образом, вы нарушите много кода. –

+0

Почему? Сколько вещей вы можете ломать, делая это? Я могу сделать 2 + 2 = 5, но может и не быть лучшим решением. Возможно, вы хотите просто настроить возвращаемое значение в нескольких особых ситуациях? – mickeyf

ответ

2

Похоже, это было возможно по abusing Строка metaClass. Но попытка я сделал до сих пор в заводной консоли не привели к ожидаемому результату:

def oldLength = String.metaClass.length 
String.metaClass.length = { -> 
    return oldLength+10; 
} 

println "hi".length() 

выводит грустная 2

Я думаю, что вы могли бы взглянуть на Proxy MetaClass или Delegating metaClass.

+0

Я думаю, проблема связана с этой проблемой: http://jira.codehaus.org/browse/GROOVY-3493 –

+1

Кажется, это работает: String.metaClass.invokeMethod = {String methodName, args -> println (" hi ") } « hi ».length() // печатает« привет » – IttayD

+0

Почему этот ответ был принят, когда по собственному признанию автора он фактически не работает? –

1

Если вы переопределили его, это будет работать только в коде Groovy. Groovy не может изменить способ выполнения Java-кода.

В Groovy "hi".length() примерно соответствует этому Java:

stringMetaClass.invokeMethod("hi","length"); 

Поскольку Groovy фактически не называют длиной непосредственно, метакласс трюки работают в Groovy кода. Но Java не знает о MetaClasses, поэтому нет возможности сделать эту работу.

+0

да, пожалуйста, покажите мне, как это сделать только для groovy – IttayD

4

Используя 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 
+0

Обратите внимание на других, которые могут удивиться, почему это не было принято в качестве ответ: он был отправлен после того, как я прокомментировал, что это решение в ответе выше – IttayD

+0

. Вы можете не принимать другой ответ и принять его, если считаете, что это лучше. Просто нажмите зеленую галочку, чтобы не принять ее. –

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