我可以重新定义String#length吗?

时间:2010-08-23 13:56:58

标签: string groovy

我想重新实现Java类的方法。例如,要"hi".length()返回4。 (我怎样才能做到这一点?

我知道使用SomeClass.metaClass我可以获得对现有方法的引用并定义新的(或重写)方法,但我似乎无法对现有的Java方法执行此操作。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

似乎可以通过abusing字符串metaClass来实现。但到目前为止我在groovy控制台中所做的尝试并未导致预期的结果:

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

println "hi".length()

输出悲伤的2

我认为您可以查看Proxy MetaClassDelegating metaClass

答案 2 :(得分:1)

如果你重新定义它,它只能在Groovy代码中工作。 Groovy无法改变Java代码的执行方式。

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

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

因为Groovy实际上并不直接调用length,所以metaClass技巧在Groovy代码中工作。但是Java并不了解MetaClasses,所以没有办法让这个工作。