Pytanie zastępując toString za pomocą metaprogramowania Groovy


W poniższym fragmencie kodu Groovy próbuję zastąpić oba hashCode i toString metody

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

Ale kiedy przetestuję to, tylko zastąpienie hashCode Prace

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

Jest toString w jakiś szczególny sposób (prawdopodobnie ze względów bezpieczeństwa)?


12
2018-05-19 10:13


pochodzenie




Odpowiedzi:


Zobacz pierwszy komentarz w tej sprawie. Jest napisane o String toString i innych klasach związanych z String:

(...) wydaje się być intencją, to prawdopodobnie   dobry pomysł na szybszą inwokację   dla klas, które nie pozwalają   nadpisywanie toString ().


5
2018-05-19 14:04



Skąd wiesz, jakie są "klasy, które nie pozwalają na przesłonięcie metody toString ()"? - Dónal
Napisałem nowy numer, który, mam nadzieję, powinien wyjaśnić ... jira.codehaus.org/browse/GROOVY- 4210 - tim_yates
Dzięki Tim, więc myślę, że krótka odpowiedź brzmi "to błąd"? - Dónal


To jest znać wadę. Zasadniczo Groovy nie nadpisuje poprawnie metod, które są częścią implementacji interfejsu.

To działa:

class T {
       def doIt() { true }
}

def t = new T()

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

To nie oznacza:

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

Bo toString() w String pochodzi z CharSequence poprawnym sposobem na zastąpienie byłoby:

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

1
2018-06-05 04:34