开发者

replacing toString using Groovy metaprogramming

In the following Groovy snippet, I attempt to replace both the hashCode and toString methods

String.metaClass.toString = {-> "override" }
String.metaClass.hashCode = {-> 22 }

But when I test it out, only the replacement of hashCode works

String s = "foo"
println s.hashCode()  // prints 22
println s.toString()  // prints "foo"

Is toString somehow a special 开发者_Go百科case (possibly for security reasons)?


See the first comment on this issue. It says about String's toString and other String related classes:

(...) seems to be intent, it is probably a good idea to have a faster invocation for classes that don't allow overriding toString().


This is a know defect. Basically Groovy does not correctly override methods that are part of an interface implementation.

This works:

class T {
       def doIt() { true }
}

def t = new T()

assert t.doIt()
t.metaClass.doIt = { -> false }
assert !t.doIt()

This doesn't:

interface I {
       def doIt()
}

class T implements I {
       def doIt() { true }
}

def t = new T()

assert t.doIt()
t.metaClass.doIt = { -> false }
assert !t.doIt()

Because toString() in String comes from CharSequence the correct way to override would be:

CharSequence.metaClass.toString = {-> "silly"}
println "hello world".toString()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜