Если у вас есть перечисления, такие как:
enum Foo {
A, B, C
}
enum Bar {
D, E, F
}
Тогда вы можете реализовать вид карты, о которой вы говорите, с помощью следующего кода.
class MyEnums {
private final Map<String, Class<? extends Enum<?>>> map = new HashMap<>();
public void addEnum(Class<? extends Enum<?>> e) {
map.put(e.getSimpleName(), e);
}
private <T extends Enum<T>> T parseUnsafely(String name) {
final int split = name.lastIndexOf(".");
final String enumName = name.substring(0, split);
final String memberName = name.substring(split + 1);
@SuppressWarnings("unchecked")
Class<T> enumType = (Class<T>) map.get(enumName);
return Enum.valueOf(enumType, memberName);
}
public Object parse(String name) {
return parseUnsafely(name);
}
public Object[] parseAll(String... names) {
return Stream.of(names)
.map(this::parse)
.collect(toList())
.toArray();
}
}
Это делает не обойти непроверенный актерский состав, хотя;это только временно скрывает это от вас.Вы можете увидеть, где, где SuppressWarnings
используется, чтобы заглушить предупреждение о enumType
.Как правило, рекомендуется применять подавление предупреждений в максимально ограниченной области.В этом случае, это для этого единственного назначения.Хотя в общем случае это может быть красный флаг, в данном случае мы знаем, что единственными значениями на карте являются, фактически, классы enum, поскольку они должны быть добавлены с помощью addEnum
.
Тогдаего можно использовать как:
MyEnums me = new MyEnums();
me.addEnum(Foo.class);
me.addEnum(Bar.class);
System.out.println(me.parse("Foo.A"));
System.out.println(me.parse("Bar.E"));
System.out.println(Arrays.toString(me.parseAll("Foo.B", "Bar.D", "Foo.C")));
, который печатает:
A
E
[B, D, C]
Вы заметите, что я разбил parseUnsafely
и parse
на отдельные методы.Причина, по которой мы не хотим раскрывать parseUnsafely
напрямую, заключается в том, что по типу возврата он дает гарантию, которую мы на самом деле не можем применить.Если бы он был выставлен, то мы могли бы написать код, подобный
Bar bar = me.parseUnsafely("Foo.B");
, который компилируется, но завершается с ошибкой во время выполнения с исключением класса приведения.