2010-05-19 10 views
12

Nella seguente frammento Groovy, tento di sostituire sia le hashCode e toString metodisostituzione toString usando Groovy metaprogramming

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

Ma quando provo fuori, la sostituzione dei soli hashCode funziona

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

È toString in qualche modo un caso speciale (probabilmente per motivi di sicurezza)?

risposta

5

Vedere il primo commento on this issue. Si dice a proposito di toString String e le altre classi relative String:

(...) sembra essere l'intento, è probabilmente una buona idea avere un'invocazione più veloce per le classi che non consentono override toString().

+0

Come ti sapere quali sono le "classi che non consentono l'override di toString()"? –

+0

Ho pubblicato un nuovo problema che dovrebbe chiarire le cose ... http://jira.codehaus.org/browse/GROOVY-4210 –

+0

Grazie Tim, quindi suppongo che la risposta breve sia "è un bug"? –

1

Questo è un know defect. Fondamentalmente Groovy non sovrascrive correttamente i metodi che fanno parte di un'implementazione dell'interfaccia.

Questo funziona:

class T { 
     def doIt() { true } 
} 

def t = new T() 

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

Questo non lo fa:

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

Perché toString() in String viene dal CharSequence il modo corretto per eseguire l'override sarebbe:

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