Since hacks to create new instances exist at various places in the internet, let’s demonstrate a simple one (compared to all those others) and the consequences:
public class EnumHack {
enum Test {
A, B, C;
}
public static void main(String[] args) throws Throwable {
Test d = (Test)MethodHandles.lookup()
.findConstructor(Test.class,
MethodType.methodType(void.class, String.class, int.class))
.invokeExact("D", 3);
System.out.println("created "+d);
try {
testSet(d);
} catch(Throwable t) {
t.printStackTrace();
}
try {
testSwitch(d);
} catch(Throwable t) {
t.printStackTrace();
}
}
static void testSet(Test t) {
EnumSet<Test> set = EnumSet.allOf(Test.class);
System.out.println("all: " + set);
if(set.add(t)) System.out.println("added " + t);
System.out.println("Set now contains " + set);
}
static void testSwitch(Test t) {
String result = switch(t) {
case A -> "a";
case B -> "b";
case C -> "c";
};
System.out.println(result);
}
}
This will print
created D
all: [A, B, C]
added D
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at java.base/java.util.RegularEnumSet$EnumSetIterator.next(RegularEnumSet.java:106)
at java.base/java.util.RegularEnumSet$EnumSetIterator.next(RegularEnumSet.java:79)
at java.base/java.util.AbstractCollection.toString(AbstractCollection.java:456)
at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)
at java.base/java.lang.StringConcatHelper.simpleConcat(StringConcatHelper.java:408)
at EnumHack.testSet(EnumHack.java:33)
at EnumHack.main(EnumHack.java:18)
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at EnumHack.testSwitch(EnumHack.java:37)
at EnumHack.main(EnumHack.java:23)
Even when you manage to alter the internally stored arrays of all constants in the runtime (there are more than one), the assumptions about the actually existing instances are compiled into the code at arbitrary places.
For code outside your control, it is very unlikely to get it to work with a changed range of valid constants for an enum type.