Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Minor
-
Resolution: Duplicate
-
Affects Version/s: 1.7.2
-
Fix Version/s: None
-
Component/s: groovy-jdk
-
Labels:None
-
Number of attachments :
Description
I assume this is a hard fix, as it is mentioned in GROOVY-2599, but the following code passes all the asserts. I would have expected them all to fail?
String.metaClass.toString = {-> "silly"} StringBuffer.metaClass.toString = {-> "silly"} StringBuilder.metaClass.toString = {-> "silly"} assert "hello world".toString() == "hello world" assert new StringBuffer("hello world").toString() == "hello world" assert new StringBuilder("hello world").toString() == "hello world"
I have added it as a new issue as I don't believe GROOVY-2599 actually covers this problem, it just crops up in the comments
Issue Links
- duplicates
-
GROOVY-3493
Cannot override methods via metaclass that are part of an interface implementation
-
The issue you are facing here is not related to toString() per se. It is about a more generic scenario where you override an interface method on the implementing class.
So, the following works because foo() is defined on a class and you override on the same class:
class Test { def foo() { "original foo" } } Test.metaClass.foo = {"new foo"} assert new Test().foo() == "new foo"But the following does not work - because now the method you override using class Foo is defined on the interface ITest.
The toString() parallel to the above is that toString() in case of String/StringBuffer/StringBuilder is defined by java.lang.CharSequence - and that is why overriding them using String/StringBuffer/StringBuilder metaclasses has no effect (same as example above)
If you change your example to the following, let's say, then all usages of toString() work as expected:
CharSequence.metaClass.toString = {-> "silly"} println "hello world".toString() println new StringBuffer("hello world").toString() println new StringBuilder("hello world").toString()