Java: final keyword and why inner classes cannot access non-final variables of an outer class

“Final” keyword in Java can be used in four contexts:

Final class – class with all the methods implicitly final, but not necessarily data members. Cannot be extended.
Final method – method that cannot be overridden.
Final primitive data members (basically primitives within the class) – cannot be reassigned once they are assigned a value.
Final object data members (basically objects within the class, eg: String, Vector…) – cannot be reassigned once they are assigned a value. However, if they are mutable they can be mutated.

Why inner classes cannot access non-final variables of an outer class in Java?

The full story is here: http://www.smotricz.com/kabutz/Issue025.html (overall an interesting newsletter, classic)
So basically the problem is because Java doesn’t use pointers as C,C++ do.
Hence, whenever class (with inner class in it) is compiled the following occurs:
1. outer class is passed as a constructor argument to the inner class
2. in special case when value of the local variable (let’s say X) can change for different instances of the inner class, compiler passes it as a constructor argument to the inner class. As a result, a new variable is created which can be changed independently in each inner class instance as well as in outer class, which shouldn’t be allowed. Hence, we have those limitations.
Hence, consider this:
public class Access2 {
    public void f() {
      for (int i=0; i<10; i++) {
	final int value = i;
	Runnable runnable = new Runnable() {
	  public void run() {
	    System.out.println(value);
	  }
	};
      }
    }
  }
Now each Runnable instance can reference variable i without any fear, because it is final and won’t change.
Overall, I wouldn’t advise using inner classes at all. I rarely find any real benefit in them.
Is it so hard to create a new class file? 🙂

Leave a comment