Search code examples
javafinal

Change a final field in Java


I have something like this:

class A {
    final int f = 1;
    int getF() {
        return f;
    }
}

class B extends A {}

Is it possible to call getF() in B class, and get 0 from it? Can this final field has another value from 1? Cause I get 0 result from getF() sometimes and have no idea what happens. No overrides or something. Just calling getF() and getting 0. In some situations. Can somebody guess why can it be like this?


Solution

  • The only combination of circumstances that I can think would allow this would be if there is another class above A that declares a method which is called by its constructor, and B overrides that method and calls getF from within there

    class Super {
      public Super() {
        doInit();
      }
    
      protected void doInit() { /* ... */ }
    }
    
    class A extends Super {
      // f and getF as before
    }
    
    class B extends A {
      protected void doInit() {
        System.out.println(getF());
      }
    }
    

    Or similarly if the constructor "leaks" a this reference to somewhere where it can be accessed before the constructor has finished running, thus breaking the usual immutability guarantees of finals.