Подтвердить что ты не робот

Заменяя toString с помощью метапрограммирования Groovy

В следующем фрагменте Groovy я пытаюсь заменить методы hashCode и toString

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

Но когда я тестирую, только замена hashCode работает

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

Является ли toString каким-то особым случаем (возможно, из соображений безопасности)?

4b9b3361

Ответ 1

См. первый комментарий по этой проблеме. Он говорит о String toString и других связанных с String классах:

(...) кажется намеренным, это, вероятно, хорошая идея иметь более быстрый вызов для классов, которые не позволяют переопределение toString().

Ответ 2

Это знать дефект. В принципе 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()