我想重新实现一个Java类的方法。例如,"hi".length()
返回4
。 (我怎样才能做到这一点?我可以重新定义String#的长度吗?
我知道使用SomeClass.metaClass我可以获得对现有方法的引用并定义新的(或重写)方法,但我似乎无法为现有的Java方法做到这一点。
我想重新实现一个Java类的方法。例如,"hi".length()
返回4
。 (我怎样才能做到这一点?我可以重新定义String#的长度吗?
我知道使用SomeClass.metaClass我可以获得对现有方法的引用并定义新的(或重写)方法,但我似乎无法为现有的Java方法做到这一点。
似乎可能通过abusing字符串metaClass。但我已经在常规控制台迄今所做的尝试没有导致预期的结果:
def oldLength = String.metaClass.length
String.metaClass.length = { ->
return oldLength+10;
}
println "hi".length()
输出伤心2
我想你可以看看Proxy MetaClass或Delegating metaClass。
我认为这个问题与这个问题有关:http://jira.codehaus.org/browse/GROOVY-3493 – 2010-08-23 14:45:00
似乎是这样,这工作:String.metaClass.invokeMethod = {String methodName,args - > println(“嗨“) } ”hi“.length()//打印”hi“ – IttayD 2010-08-24 04:34:46
为什么当作者自己承认它不实际工作时接受了此答案? – 2010-08-24 07:47:21
如果您确实重新定义了它,它只能在Groovy代码中使用。 Groovy无法改变Java代码执行的方式。
在Groovy,"hi".length()
大致相当于这个Java:
stringMetaClass.invokeMethod("hi","length");
因为Groovy实际上并没有通话时长直接的metaClass技巧在Groovy代码工作。但Java不知道MetaClass,所以没有办法做到这一点。
是的,请告诉我如何做只适合groovy – IttayD 2010-08-23 20:15:34
使用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
注意到其他人可能会问,为什么这不被接受为答案:在我评论说这是上述答案中的解决方案之后提交的答案 – IttayD 2010-08-25 11:06:26
如果您觉得它更好,您可以不接受其他答案并接受此答案。只需点击绿色复选标记即可不接受。 – 2010-08-26 16:58:28
这将是不正确的行为。你可以使用'pad()'方法来扩展你的字符串到给定的最大长度。然后你可以调用该字符串的长度。 – Nate 2010-08-23 13:58:52
你喜欢用什么来实现?你会以这种方式破坏很多代码。 – 2010-08-23 14:00:21
为什么?你做这件事有多少事情可能会被打破?我可以使2 + 2 = 5,但可能不是真正的最佳解决方案。也许你想在几种特殊情况下简单地调整返回值? – mickeyf 2010-08-23 14:01:31