我偶然发现了这个。这是短篇小说。在某些代码库中,有一堆遵循相同模式的枚举,下面是一个大大简化的枚举:
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));
}
}
从字面上看,这是一个跨越数十个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:无效的接收者类型类java.lang.Enum;不是实现类型接口GetValueInterface的子类型
在java-11
下运行相同的代码就可以了...
答案 0 :(得分:2)
准备好此问题20分钟后,我进行了一次Google搜索,并立即发现了问题:| this one
修复很容易,只需使用lambda表达式即可:
(T t) -> t.getValue() // instead of T::getValue