budynek na odpowiedź od @assylias, myślę, że to jest najlepsze, co możesz zrobić:
List<String> unknown = new ArrayList<>();
for (TestEnum e : TestEnum.values())
unknown.add(e.name());
unknown.removeAll(Arrays.asList("YES", "NO"));
if (unknown.isEmpty()) {
// Not possible to reach default case, do whatever you need to do
} else {
TestEnum notIncluded = TestEnum.valueOf(unknown.get(0));
workTheEnum(notIncluded);
}
to nie jest możliwe (AFAIK) do fałszywej nieistniejącej wartości enum
w switch
stwierdzeniem, ze względu na sposób, że enum
Instrukcje switch są kompilowane. Nawet jeśli użyjesz wewnętrznego pola ordinal
w instancji enum
za pomocą odbicia, instrukcja switch
da raczej ArrayIndexOutOfBoundsException
niż przechodzenie do obudowy default
.
Oto kod, który wygląda jak to może działać, ale nie ze względu na ArrayIndexOutOfBoundsException
mowa powyżej:
TestEnum abused = TestEnum.YES;
try {
Class<?> c = abused.getClass().getSuperclass();
Field[] declaredFields = c.getDeclaredFields();
Field ordinalField = null;
for (Field e : declaredFields) {
if (e.getName().equals("ordinal")) {
ordinalField = e;
}
}
ordinalField.setAccessible(true);
ordinalField.setInt(abused, TestEnum.values().length);
workTheEnum(abused);
} catch (Exception e) {
e.printStackTrace(System.err);
}
OK, tutaj jest coś, co może pracować dla Ciebie . To jest dość hacky, więc dla mnie jest to prawdopodobnie gorsze niż brak 100% pokrycia kodu, YMMV. Działa poprzez zastąpienie tablic wyliczeniowych porządkowych wyliczeniowych z tablicami zawierającymi wszystkie zera, które przenikają do domyślnego przypadku.
// Setup values - needs to be called so that
// $SWITCH_TABLE$FooClass$BarEnum is initialised.
workTheEnum(TestEnum.YES);
workTheEnum(TestEnum.NO);
// This is the class with the switch statement in it.
Class<?> c = ClassWithSwitchStatement.class;
// Find and change fields.
Map<Field, int[]> changedFields = new HashMap<>();
Field[] declaredFields = c.getDeclaredFields();
try {
for (Field f : declaredFields) {
if (f.getName().startsWith("$SWITCH_TABLE$")) {
f.setAccessible(true);
int[] table = (int[])f.get(null);
f.set(null, new int[table.length]);
changedFields.put(f, table);
}
}
workTheEnum(TestEnum.YES);
} finally {
for (Map.Entry<Field, int[]> entry : changedFields.entrySet()) {
try {
entry.getKey().set(null, entry.getValue());
} catch (Exception ex) {
ex.printStackTrace(System.err);
}
}
}
Nie jestem wystarczająco pewny siebie, twierdząc, że to jest odpowiedź, ale: Czy nie jest możliwe zrobienie 'TestEnum notAValidEnum = Mockito.mock (TestEnum.class);', a następnie podanie to do 'WorkTheEnum()' ...? – kinbiko
Prawdopodobny duplikat: https://stackoverflow.com/questions/5323505 – augurar