Хороший вопрос, удивительный момент в приведенном выше коде состоит в том, что
println "${'test'}".equals('test')
возвращает false
.Другая строка кода возвращает ожидаемый результат, поэтому давайте забудем об этом.
Сводка
"${'test'}".equals('test')
Объект, для которого вызывается equals
, имеет тип GStringImpl
, тогда как 'test'
имеет тип String
, поэтому они не считаются равными.
Но почему?
Очевидно, что GStringImpl
реализация equals
могла бы быть написана так, чтобы при ее передачеString
, содержащие те же символы, что и this
, возвращает значение true.На первый взгляд, это кажется разумным.
Я предполагаю, что причина, по которой он не был написан таким образом, заключается в том, что он нарушил бы контракт equals
, который гласит:
Это симметрично: для любых ненулевых ссылочных значений x и y x.equals (y) должен возвращать true, если и только если y.equals (x) возвращает true.
Реализация String.equals(Object other)
всегда будет возвращать false при передаче GSStringImpl
, поэтому, если GStringImpl.equals(Object other)
вернет true при передаче любого String
, это будет нарушением симметричного требования.