10
votes

I am hoping to get an explanation as to why the call to this Groovy method works as expected:

def f1(int n) {
  return n + 1
}
println f1(1) // -> 2

But, if the parameter is not specifically defined ("def n" instead of "int n"), the method call needs to change:

def f2(def n) {
  return n + 1
}
println f2(1) // Exception: Illegal class name
println this.&f2(1) // -> 2

What is happening under the hood to make this necessary?

UPDATED with more info:

This is on Windows with Groovy 2.4.5 JVM 1.8.0_51

The entire script is those 9 lines in a file called 1.groovy - nothing else.

I am running this from the console (cmdr) using "groovy 1.groovy"

The error on line 8 is:

Caught: java.lang.ClassFormatError: Illegal class name "3$f2" in class file 3$f2 java.lang.ClassFormatError: Illegal class name "3$f2" in class file 3$f2 at 3.run(3.groovy:8)

1
What about def f3(n) {...? Also what version of Groovy is this? - doelleri
f2(1) works fine for me. Be aware that adding def to method params is totally unnecessary. - Nathan Hughes
I don't have any issue with your example, tested in the groovy webconsole or in a java application. It's probably related to a context you didn't show here - Jérémie B
This is on Windows with Groovy 2.4.5 JVM 1.8.0_51 - the entire script is those 9 lines. The error on line 8 is: Caught: java.lang.ClassFormatError: Illegal class name "3$f2" in class file 3$f2 java.lang.ClassFormatError: Illegal class name "3$f2" in class file 3$f2 at 3.run(3.groovy:8) - Jahg Daglet
doelleri - dropping the def from the parameter - def f2(n) {} - throws the exception, as well - Jahg Daglet

1 Answers

21
votes

This is related to the name of your Script. When you have a file "1.groovy", Groovy generate a class with the name "1" in the default package, which is not a valid class name.

When you use f2(n) without a type, as this method is "too generic", Groovy try to find a matching method, or a class named f2, or an inner class named f2 : loading an inner class f2 of the class 1 fail, because the name is invalid.