2010-05-19 12 views
12

En el siguiente fragmento maravilloso, yo intento de sustituir tanto los métodos hashCode y toStringreemplazando toString usando Groovy metaprogramming

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

Pero cuando lo pruebo a cabo, sólo la sustitución de hashCode funciona

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

¿Es toString de alguna manera un caso especial (posiblemente por razones de seguridad)?

Respuesta

5

Ver el primer comentario on this issue. Se dice acerca de toString de cuerdas y otras clases relacionadas con Cuerda:

(...) parece ser la intención, es probablemente una buena idea tener una invocación más rápido para las clases que no permiten toString anulando().

+0

Cómo hacer que saber cuáles son las "clases que no permiten anular toString()"? –

+0

Publiqué un nuevo problema que espero que aclare las cosas ... http://jira.codehaus.org/browse/GROOVY-4210 –

+0

Gracias Tim, ¿así que supongo que la respuesta corta es "es un error"? –

1

Esto es know defect. Básicamente Groovy no sobrescribe correctamente los métodos que forman parte de una implementación de interfaz.

Esto funciona:

class T { 
     def doIt() { true } 
} 

def t = new T() 

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

Esto no es así:

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

Debido toString() en StringCharSequence proviene de la forma correcta para anular sería:

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