Only the definition of final string obj does not error public
void Test (final String obj)
{
thread mythread = new Thread () {
publi c void Run () {
System.out.println (obj);
}
};
Mythread.start ();
}
public class Outerclass {public
void outerdosomething () {
final String localobj = "Hello";
Innerclass innerobj = new class Innerclass {public
void innerdosomething () {
//does with Localobj
}
};
}
}
If you decompile an inner class that accesses the final local variable, you can see that the variable was passed in as a constructor parameter, and of course the arguments passed in with the external class reference this.
Actually compiled, the byte code generated is as follows:
public class Outerclass {public
void outerdosomething () {
final String localobj = "Hello";
Class innerclass{
private String obj;
Public innerclass (String obj) {
this.obj = obj;
}
public void innerdosomething () {
//does with obj
}
};
Innerclass innerobj = new Innerclass (localobj);
}
}
absurd Reason: Java unexpectedly allows internal class objects to access local variables.
Know that the life cycle of a local variable is inconsistent with the life cycle of the object of the local inner class. A local variable is dead after the execution of the function is completed, does not exist, but the local inner class object may still exist (as long as someone also references the object), and this is the result of a tragic, local inner class object accessing a local variable that no longer exists.
In order to avoid this situation, Java invented the above mechanism, secretly put the reference of local variables in the internal class object member variables.
But after solving the lifecycle problem, another problem arises, because the variables used in local variables and internal classes are the same object.
For example, the following example, and if final is not enforced, we simply do not know what object obj is in the execution:
public class HelloWorld
{public
void Test ()
{
String obj = "Hello";//Do not use final
Thread mythread = new Thread () {public
void run () {
System.out.println (obj);//OJB exactly.
}
};
Mythread.start ();
}
public static void Main (String [] argv)
{
HelloWorld hello = new HelloWorld ();
Hello.test ();
}
Like the following example,
public class HelloWorld
{public
void Test ()
{
String obj = "Hello";//no final Thread is used
Mythread = new Thread () {public
void run () {
}
};
Mythread.start ();
System.out.println (obj); What exactly is obj.
}
public static void Main (String [] argv)
{
HelloWorld hello = new HelloWorld ();
Hello.test ();
}