使用Groovy元编程替换toString

时间:2010-05-19 10:13:16

标签: groovy metaprogramming

在以下Groovy代码段中,我尝试替换hashCodetoString方法

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

但是当我测试它时,只有替换hashCode才能正常工作

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

toString是某种特殊情况(可能出于安全原因)吗?

2 个答案:

答案 0 :(得分:5)

查看第一条评论on this issue。它说的是String的toString和其他与String相关的类:

  

(...)似乎是意图,它可能是一个   有一个更快的调用的好主意   对于不允许的类   重写toString()。

答案 1 :(得分:1)

这是know defect。 基本上,Groovy没有正确覆盖作为接口实现一部分的方法。

这有效:

class T {
       def doIt() { true }
}

def t = new T()

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

这不是:

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()

由于toString()中的String来自CharSequence,正确的覆盖方式是:

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