Xae*_*ess 6 java generics enums guava
我试图通过使用Guava 迭代es 列表来对几个实现相同接口的枚举类进行反向查找:FieldClassMaps.uniqueIndex
Field valueOfSearchName = null;
for (final Class<? extends Enum<?>> clazz : ImmutableList.of(
EntityField.class,
AddressField.class,
PersonFunctionType.class)) {
valueOfSearchName = Fields.valueOfSearchName(clazz, term.field()); // error
if (valueOfSearchName != null) {
// do something...
break;
}
}
Run Code Online (Sandbox Code Playgroud)
我不想在所有枚举类中重复相同的代码(用于制作索引和执行查找),因此我使用Fields包含Fields.valueOfSearchName方法的辅助静态类:
public static <E extends Enum<E> & Field> Field valueOfSearchName(
final Class<E> clazz, final String searchName) {
// TODO: cache the index
final ImmutableMap<String, E> index = Maps.uniqueIndex(
EnumSet.allOf(clazz), GET_SEARCH_NAME_FUNCTION);
return index.get(searchName);
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,Eclipse显示错误:
Bound mismatch:
The generic method valueOfSearchName(Class<E>, String) of type Fields is not
applicable for the arguments (Class<capture#1-of ? extends Enum<?>>, String).
The inferred type capture#1-of ? extends Enum<?> is not a valid substitute
for the bounded parameter <E extends Enum<E> & Field>
Run Code Online (Sandbox Code Playgroud)
问题是Class<? extends Enum<?>> clazz在for-each循环(不匹配字段),但我不知道如何处理这种情况下(很明显,我不能添加& Field到clazz).
受到Tom Hawtin 答案的Class启发,我创建了包含es的包装类,但仅限于那些带有签名的包装类<E extends Enum<E> & Field>:
public final static class FieldEnumWrapper<E extends Enum<E> & Field> {
private final Class<E> clazz;
private final ImmutableMap<String, E> index;
public static <E extends Enum<E> & Field>
FieldEnumWrapper<E> of(final Class<E> clazz) {
return new FieldEnumWrapper<E>(clazz);
}
private FieldEnumWrapper(final Class<E> clazz) {
this.clazz = clazz;
this.index = Maps.uniqueIndex(
EnumSet.allOf(clazz), new Function<E, String>() {
@Override
public String apply(final E input) {
return input.searchName();
}
});
}
public Class<E> clazz() {
return clazz;
}
public Field valueOfSearchName(final String searchName) {
return index.get(searchName);
}
}
Run Code Online (Sandbox Code Playgroud)
现在:
for (final FieldEnumWrapper<?> fieldEnum : ImmutableList.of(
FieldEnumWrapper.of(EntityField.class),
FieldEnumWrapper.of(AddressField.class),
FieldEnumWrapper.of(PersonFunctionType.class))) {
valueOfSearchName = fieldEnum.valueOfSearchName("POD_I_OS_PARTNER");
// ...
Run Code Online (Sandbox Code Playgroud)
是类型安全的并且不恰当地使用 的FieldEnumWrapper静态工厂:
FieldEnumWrapper.of(NotEnumAndFieldClass.class)
Run Code Online (Sandbox Code Playgroud)
产生编译错误。
此外,valueOfSearchName现在是FieldEnumWrapper帮助类更有意义的方法。