2010-05-19 8 views
12

Dans l'extrait Groovy suivant, je tente de remplacer les deux hashCode et toString méthodesremplaçant toString utilisant Groovy metaprogramming

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

Mais quand je le tester, seul le remplacement des hashCode fonctionne

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

Est-ce que toString est un cas particulier (peut-être pour des raisons de sécurité)?

Répondre

5

Voir le premier commentaire on this issue. Il dit à propos toString String et d'autres classes liées à cordes:

(...) semble être l'intention, il est probablement une bonne idée d'avoir une invocation plus rapide pour les classes qui ne permettent pas remplaçant toString().

+0

Comment comptez-vous savoir quelles sont les "classes qui ne permettent pas de surcharger toString()"? –

+0

J'ai posté un nouveau numéro qui, je l'espère, devrait éclaircir les choses ... http://jira.codehaus.org/browse/GROOVY-4210 –

+0

Merci Tim, donc je suppose que la réponse courte est "c'est un bug"? –

1

Ceci est un know defect. Fondamentalement, Groovy ne remplace pas correctement les méthodes faisant partie d'une implémentation d'interface.

Cela fonctionne:

class T { 
     def doIt() { true } 
} 

def t = new T() 

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

Cela ne signifie pas:

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

Parce que toString() en String vient de CharSequence la bonne façon de passer outre serait:

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