Question:
In some sources, in the literature, they write just such a statement. My question is, "Is this statement absolute?" Or is it done specifically for general understanding?
I read here on the forum that there is reflection and that you can still influence it. Are there other possibilities?
Answer:
It all depends on what these modifiers are used for:
- If the
final
modifier is used for a class field , then the field must be defined in the class constructor (and once for the entire constructor), or, directly, at the place of the declaration.The collection of
private final
modifiers for a field imposes a prohibition on changing (it is possible to define this field either in the constructor or in the place of declaration at the expense offinal
) and the visibility of this field is limited by the methods of this class (due toprivate
). - If the
final
modifier is used for a class method , then it prohibits overriding this method in derived classes.The use of a pair of
private final
modifiers for a class method is meaningless, sinceprivate
restrict access to this method to the limits of the class, andfinal
prohibit its redefinition in its heirs. those. descendants will not see this method, and therefore will not be able to override.
When using reflection, the value of a field with the private
modifier can be changed, but this is not allowed for a final
field (no exception / warning will be generated, but the field will not change).
Test case:
class WithPrivateFinalField {
private int i = 1;
private final String s = "String S";
private String s2 = "String S2";
public String toString() {
return "i = " + i + ", " + s + ", " + s2;
}
}
public class ModifyngPrivateFields {
public static void main(String[] args) throws Exception {
WithPrivateFinalField pf = new WithPrivateFinalField();
Field f = pf.getClass().getDeclaredField("i");
f.setAccessible(true);
f.setInt(pf, 47);
System.out.println(pf); // i = 47, String S, String S2
f = pf.getClass().getDeclaredField("s");
f.setAccessible(true);
f.set(pf, "MODIFY S");
System.out.println(pf); // i = 47, String S, String S2
f = pf.getClass().getDeclaredField("s2");
f.setAccessible(true);
f.set(pf, "MODIFY S2");
System.out.println(pf); // i = 47, String S, MODIFY S2
}
}