import java.util.*;
import java.lang.reflect.*;

enum Color {RED, BLUE, GREEN};

class Example {
    public static void main(String[] args) throws Exception {
        // use the Field at least once so it creates and caches accessors
        // with the final modifier
        System.out.println(Arrays.toString((Object[]) getValuesField(Color.class).get(null)));
        
        // now throws IllegalAccessException, because removing
        // the final modifier has no effect (IllegalAccessException
        // is thrown by the field accessor)
        try {
            setEnumsArray(Color.class, Color.RED, Color.RED, Color.RED);
        } catch (IllegalAccessException x) {
            System.out.println(x);
            System.out.println("    at " + x.getStackTrace()[0]);
        }
        
        // clear accessors
        clearFieldAccessors(getValuesField(Color.class));
        // now it works
        setEnumsArray(Color.class, Color.RED, Color.RED, Color.RED);
        
        System.out.println(Arrays.toString(Color.values()));
    }
    
    static Field getValuesField(Class<?> c) throws Exception {
        Field f = c.getDeclaredField("$VALUES");
        f.setAccessible(true);
        return f;
    }
    
    static <E extends Enum<E>> void setEnumsArray(Class<E> ec, E... e) throws Exception {
        Field field = getValuesField(ec);
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        field.setAccessible(true);
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        field.set(ec, e);
    }
    
    static void clearFieldAccessors(Field field)
            throws ReflectiveOperationException {
        Field fa = Field.class.getDeclaredField("fieldAccessor");
        fa.setAccessible(true);
        fa.set(field, null);
    
        Field ofa = Field.class.getDeclaredField("overrideFieldAccessor");
        ofa.setAccessible(true);
        ofa.set(field, null);
    
        Field rf = Field.class.getDeclaredField("root");
        rf.setAccessible(true);
        Field root = (Field) rf.get(field);
        if (root != null) {
            clearFieldAccessors(root);
        }
    }
}