2010-08-23 53 views
7

我想重新实现一个Java类的方法。例如,"hi".length()返回4。 (我怎样才能做到这一点?我可以重新定义String#的长度吗?

我知道使用SomeClass.metaClass我可以获得对现有方法的引用并定义新的(或重写)方法,但我似乎无法为现有的Java方法做到这一点。

+0

这将是不正确的行为。你可以使用'pad()'方法来扩展你的字符串到给定的最大长度。然后你可以调用该字符串的长度。 – Nate 2010-08-23 13:58:52

+0

你喜欢用什么来实现?你会以这种方式破坏很多代码。 – 2010-08-23 14:00:21

+0

为什么?你做这件事有多少事情可能会被打破?我可以使2 + 2 = 5,但可能不是真正的最佳解决方案。也许你想在几种特殊情况下简单地调整返回值? – mickeyf 2010-08-23 14:01:31

回答

2

似乎可能通过abusing字符串metaClass。但我已经在常规控制台迄今所做的尝试没有导致预期的结果:

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

println "hi".length() 

输出伤心2

我想你可以看看Proxy MetaClassDelegating metaClass

+0

我认为这个问题与这个问题有关:http://jira.codehaus.org/browse/GROOVY-3493 – 2010-08-23 14:45:00

+1

似乎是这样,这工作:String.metaClass.invokeMethod = {String methodName,args - > println(“嗨“) } ”hi“.length()//打印”hi“ – IttayD 2010-08-24 04:34:46

+0

为什么当作者自己承认它不实际工作时接受了此答案? – 2010-08-24 07:47:21

1

如果您确实重新定义了它,它只能在Groovy代码中使用。 Groovy无法改变Java代码执行的方式。

在Groovy,"hi".length()大致相当于这个Java:

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

因为Groovy实际上并没有通话时长直接的metaClass技巧在Groovy代码工作。但Java不知道MetaClass,所以没有办法做到这一点。

+0

是的,请告诉我如何做只适合groovy – IttayD 2010-08-23 20:15:34

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 2010-08-25 11:06:26

+0

如果您觉得它更好,您可以不接受其他答案并接受此答案。只需点击绿色复选标记即可不接受。 – 2010-08-26 16:58:28

相关问题