Я наткнулся на это случайно.Вот рассказ.В некоторой кодовой базе есть множество перечислений, которые следуют одному и тому же шаблону, вот тот, который очень упрощен:
enum Letters {
A("a"),
Z("z");
private String value;
Letters(String value) {
this.value = value;
}
private static final Map<String, Letters> MAP;
public String getValue() {
return value;
}
static {
MAP = Arrays.stream(values())
.collect(Collectors.collectingAndThen(
Collectors.toMap(
Letters::getValue,
Function.identity()
),
ImmutableMap::copyOf
));
}
public static Optional<Letters> fromValue(String value) {
return Optional.ofNullable(MAP.get(value));
}
}
Это шаблон буквально для десятков Enums, и нет, это не может 'не может быть изменено.Я думал об изменении этого дублирования кода, так как его много .
Моя идея состояла в том, чтобы начать с интерфейса enum, который все будут реализовывать:
interface GetValueInterface {
String getValue();
}
И некоторый общий код, который будет обрабатывать это создание MAP (fromValue
также будет обрабатываться там,но давайте отложим это в сторону).Итак, что-то вроде этого:
static class EnumsCommon {
public static <T extends Enum<T> & GetValueInterface> Map<String, T> getAsMap(Class<T> clazz) {
T[] values = clazz.getEnumConstants();
return Arrays.stream(values)
.collect(Collectors.collectingAndThen(
Collectors.toMap(
T::getValue,
Function.identity()
),
ImmutableMap::copyOf
));
}
}
Итак, код выглядит следующим образом:
enum Letters implements GetValueInterface {
// everything else stays the same
static {
MAP = EnumsCommon.getAsMap(Letters.class);
}
}
Это прекрасно компилируется, но когда я запускаю его под java-8
, появляетсявыброшено исключение:
Причина: java.lang.invoke.LambdaConversionException: недопустимый тип получателя class java.lang.Enum;не подтип интерфейса реализации типа GetValueInterface
Запуск того же кода в java-11
работает просто отлично ...