The Groovy compiler doesn't seem to like this generic method.
@CompileStatic
class GroovyMain {
enum Planet { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE }
enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }
static void main(String... args) {
Planet p = getEnumValueFor('Venus', Planet.&valueOf, Planet.EARTH)
Day d = getEnumValueFor('Sunday', Day.&valueOf, Day.MONDAY)
println "$p $d"
}
static <T extends Enum<T>> T getEnumValueFor(String value, Closure<T> closure, T defaultValue) {
try {
return closure.call(value.toUpperCase())
} catch (Exception ignore) {
return defaultValue
}
}
}
I can "fix" this in at least three ways.
- remove
@CompileStatic
- remove the generic bound
extends Enum<T>
- cast the result of the closure call
But these options reduce or eliminate type safety. Is there another way to satisfy the groovy compiler?
For reference, the equivalent Java code compiles without error.
class JavaMain {
enum Planet { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE }
enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }
public static void main(String... args) {
Planet p = getEnumValueFor("Venus", Planet::valueOf, Planet.EARTH);
Day d = getEnumValueFor("Sunday", Day::valueOf, Day.MONDAY);
System.out.print("" + p + ' ' + d);
}
static <T extends Enum<T>> T getEnumValueFor(String value, Function<String, T> closure, T defaultValue) {
try {
return closure.apply(value.toUpperCase());
} catch (Exception ignore) {
return defaultValue;
}
}
}