Może to zabrzmi trochę dziwnie, ale czy w czasie wykonywania można dodać modyfikator final
?Dodaj ostateczny modyfikator w środowisku wykonawczym w Javie
Mam zmienną, która jest oznaczona jako public static int/short
. W pewnym momencie chcę zapobiec zmianie jego wartości i chcę zachować jego dostępność jako standardowej wartości statycznej (ClassName.field
).
public class Main {
private static int a = 0;
public static void addFinalMod(Field f) {
Field modifiersField = null;
try {
modifiersField = Field.class.getDeclaredField("modifiers");
}
catch (NoSuchFieldException e) {
e.printStackTrace();
}
modifiersField.setAccessible(true);
try {
modifiersField.setInt(f, f.getModifiers() & Modifier.FINAL);
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println(a);
try {
Field f = Main.class.getDeclaredField("a");
addFinalMod(f);
}
catch (NoSuchFieldException e) {
e.printStackTrace();
}
a = 10; //I was expecting error/exception here
System.out.println(a);
}
wyjściowa:
0
10
To całkiem interesujące pytanie. Na razie wydaje mi się, że reguły 'final' są sprawdzane tylko podczas kompilacji (dotyczy to zarówno wymagań inicjalizacyjnych, jak i gwarancji JMM). –
Myślę, że masz na myśli 'f.getModifiers() | Modifier.FINAL' zamiast 'f.getModifiers() & Modifier.FINAL', aby pozostały inne modyfikatory. Również jeśli użyjesz 'f.set (null, 5); 'dostaniesz oczekiwany wyjątek. – Pshemo