Could anyone please tell me what is the meaning of the following line in context of Java:
final variable can still be manipulated unless it\'s immut
The following is code I created several years back to turn final off and then back on so you can modify the reference/value, it will only work on variables, but it does work.
You can also do something similar with method handles, however unless you are writing some form of auto object parser/generator, I would avoid doing either like the plague.
public static void setValueOnField(Object instance, Field field, Object value)
throws NoSuchFieldException, IOException, IllegalArgumentException,
IllegalAccessException {
try (Accessor access = open(field)) {
field.set(instance, value);
}
}
public static class Accessor
implements Closeable {
private final boolean isAccessible;
private final boolean isFinal;
private final int modifiers;
private final T accessibleObject;
private Accessor(T accessibleObject) throws IOException {
super();
if (accessibleObject == null) {
throw new IOException(
"Error preparing field for accesibility: Field is null");
}
try {
this.accessibleObject = accessibleObject;
this.modifiers = accessibleObject.getModifiers();
this.isAccessible = accessibleObject.isAccessible();
this.isFinal = Modifier.isFinal(modifiers);
if (!this.isAccessible) {
accessibleObject.setAccessible(true);
}
if (this.isFinal) {
getModifiersField(accessibleObject).setInt(
accessibleObject, modifiers & ~Modifier.FINAL);
}
} catch (Exception e) {
throw new IOException("Error preparing field for accesibility",
e);
}
}
@Override
public void close() throws IOException {
if (!this.isAccessible) {
accessibleObject.setAccessible(false);
}
if (this.isFinal) {
try {
getModifiersField(accessibleObject).setInt(
accessibleObject, modifiers);
} catch (Exception e) {
throw new IOException("Error setting field to final", e);
}
}
}
public T getAccessibleObject() {
return accessibleObject;
}
private static Field getModifiersField(AccessibleObject toFetch) {
Field field;
try {
field = toFetch.getClass().getField("modifiers");
field.setAccessible(true);
return field;
} catch (Exception e) {
throw new RuntimeException(
"Error occured getting modifiers field", e);
}
}
}