2010-05-19 51 views
12

在下面的Groovy片段取代的toString,我試圖更換兩個hashCodetoString方法使用Groovy元編程

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

但是當我測試它,只有更換hashCode工作

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

toString以某種方式是特例(可能出於安全原因)?

回答

5

查看第一條評論on this issue。它說,關於字符串的toString等字符串相關的類:

(...)似乎是意圖,它可能是有階級更快的調用 不允許 覆蓋的toString一個 好主意()。

+0

你如何知道哪些是「不允許覆蓋toString()」的類? – 2010-05-19 14:13:04

+0

我發佈了一個新問題,希望能夠解決這些問題...... http://jira.codehaus.org/browse/GROOVY-4210 – 2010-05-19 17:05:41

+0

謝謝蒂姆,所以我想簡短的回答是「這是一個錯誤」? – 2010-05-20 08:41:00

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