It might sound a bit strange, but is it possible to add the final
modifier at runtime?
I have a variable which is marked as public static int/short
. At certain point I want to prevent changing its value, and I want to keep its accessibility as a standard static value (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);
}
Output:
0
10
Final variable in Java cannot be changed. Once if we have assigned the final variable it can not be changed it is fixed. but if you have declare a blank final variable then you can assign value to it only in constructor.
In Java final is the access modifier which can be used with a filed class and a method. When a method if final it cannot be overridden. When a variable is final its value cannot be modified further. When a class is finale it cannot be extended.
The final keyword is a non-access modifier used for classes, attributes and methods, which makes them non-changeable (impossible to inherit or override). The final keyword is useful when you want a variable to always store the same value, like PI (3.14159...). The final keyword is called a "modifier".
Classes marked as final can't be extended. One example is the String class.
At certain point I want to prevent changing its value
Do that in application logic. Make the variable only accessible through methods. Keep a flag tracking any change to the variable. After you've applied the change or reached the certain point, raise the flag, and throw an exception for any further attempts at changing the variable.
final
is a language keyword/feature for writing your source code and preventing re-assignment of a variable in source code. At runtime, it does (almost) nothing.
Use an immutable object:
public class Thing {
private int value;
public Thing(int value) { this.value = value; }
public int getValue() { return this.value; }
}
Then just replace it when it needs modification:
Thing x = Thing(1);
// do some stuff
x = Thing(2);
// more stuff
If you're thinking, "But then they can still modify the value by replacing the object!" well, of course. The only way to prevent that is to lock down some global state (which is actually impossible if it's not a constant), but you're not using global state, right? Global state is a Bad ThingTM.
Global state has a very simple problem: it makes your code much less reusable and more error prone. Error prone is especially true if you're modifying that global state at runtime. "Aw, crap, things are happening in the wrong order." You have no idea how easy that is. Trying to track order of events is the reason mutlithreading is so hard. In terms of reusability, it means that you can't have two independent instances of the thing, which in turn implies you can't really have any two instances of anything that depends on it (at least when it turns out you needed to vary this thing after all).
Even if this isn't a global, then this is some weird state that everyone who has to modify your code (including yourself) is going to have to be aware of and thinking about as they make changes. Does that sound like it's going to make changing things easier or harder? (Hint: the latter.) Don't do this to yourself or your coworkers. Make it simpler. Take a lesson from the Zen of Python: "Simple is better than complex."
So bottom line: if you need an immutable object, use an immutable object. If you need an immutable global that's not a constant, figure out a better way to organize your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With