Groovy @CompileStatic с ограниченными дженериками - PullRequest
0 голосов
/ 14 июня 2019

Компилятору Groovy не нравится этот универсальный метод.

@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
        }
    }
}

Я могу «исправить» это, по крайней мере, тремя способами.

  • удалить @CompileStatic
  • удалить общую границу extends Enum<T>
  • приведёт результат вызова закрытия

Но эти опции уменьшают или исключают безопасность типов. Есть ли другой способ удовлетворить отличный компилятор?

Для справки, эквивалентный код Java компилируется без ошибок.

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;
        }
    }
}
...