Saturday, July 18, 2009

Accessing local variables in local classes

In Java, local classes can access any members of the containing class. However when it comes to local variables and method parameters they can use only the ones marked final.  The reason is that the instances of the class can live longer than the method.  And since local variables and method parameters live on the stack, they may be long gone before the instance actually uses them.  So if the local classes want to use local variables, they must have a private copy of all the local variables they use. The compiler automatically makes a private internal copy for the local class. However the value of the local variable can change during the lifetime of the method. So someone has to keep the private local variable of the local class in sync with the actual local variable. There are many issues involved in doing it (like when or how often should the sync take place etc). The safest and perhaps the easiest way to guarantee that the local and the private copy are same is to mark the local variable final.  Hence the local classes cannot use local variables and method parameters that are not marked final.  Here is an example of how an instance of a local class can save the scope and use it at a later point in time:





public class LocalClass {

private int instanceVariable = 0;
private interface LocalClassHolder{
int getInstanceVariable();
int getLocalVariable();
}

public LocalClassHolder testLocalClass() {

final int localVariable = 1;
LocalClassHolder lch;
int changingLocalVariable = 0; //not possible to use this in local class

class InnerLocalClass implements LocalClassHolder {
//return instance variable
public int getInstanceVariable() {
return instanceVariable;
}

//return local variable
public int getLocalVariable() {
return localVariable;
}
}
lch = new InnerLocalClass();
changingLocalVariable = 1000;
return lch;

}

public static void main(String[] args) {
LocalClass lc = new LocalClass();
LocalClassHolder ch = lc.testLocalClass();
int instance = ch.getInstanceVariable();
int local = ch.getLocalVariable();
System.out.println("Instance: " + instance + " " + "Local: " + local);

}

}


No comments:

Post a Comment