[Edit: Some documentation has been added to clarify this issue -- see Groovy's Extended Guide to Method Signatures on the wiki. And now that I've read through the documentation and grok the way that Groovy is intending to work, I actually like it. At first, though, it was a bit of a nasty shock.]
Running this in the groovyConsole:
void custom(Class cls, Map args) { println cls.name + " " + args } custom(Integer.class, foo:"Bar!")
Explodes like this:
groovy.lang.MissingMethodException: No signature of
method: Script3.custom() is applicable for argument
types: (java.util.LinkedHashMap, java.lang.Class)
values: {[foo:Bar!], class java.lang.Integer}
at Script3.run(Script3:5)
I expect the explosion, but it looks like the types of my arguments are getting swapped around before it explodes. In fact, if I swap the order of the arguments around at the call site…
void custom2(Map args, Class cls) { println cls.name + " " + args } custom2(Integer.class, foo:"Bar!")
…the code runs without a hitch.
It turns out that Groovy intentionally reorganizes arguments passed into a method for you, beginning with the naked map, then normal arguments, then varargs.
More at my (closed, “Not a Bug” JIRA ticket): GROOVY-3006. See also Groovy-3009 for more issues with method reordering.
Related posts: