Cannot refer to a non-final variable mylis inside an inner class defined in a different method

Source: Internet
Author: User

This problem happened when I tested the publishing and subscription mode of Jedis today. The anonymous internal class cannot reference non-final variables in the external class.

You can see that the reasons are as follows:

The local anonymous class is Source code After compilation, the corresponding class file (usually a $1. the binary file is independent of its peripheral class (. class), that is, it cannot know the variable of the method in Class. But a $1. class does need to access the local variable value of the method corresponding to Class... What should we do? Therefore, the system simply requires that "the local variable in the method called by the anonymous internal class must be final", so that a $1. Class accesses the local variable part of the Class A method and directly uses a constant to represent it.
This is a problem in compiler design. It is easy to understand if you understand the Java compilation principles.
First, an internal class. Class file is generated when the internal class is compiled. This file is not in the same class file as the external class.
When the parameters passed by the external class are called by the internal class Program For example:
Public void dosome (final string a, final int B ){
Class dosome {public void dosome () {system. Out. println (a + B )}};
Dosome some = new dosome ();
Some. dosome ();
}
Slave Code It seems that it is the and B parameters directly called by the internal class, but it is actually not. The actual operation code after the Java compiler compilation is
Class outer $ dosome {
Public dosome (final string a, final int B ){
This. dosome $ A =;
This. dosome $ B = B;
}
Public void dosome (){
System. Out. println (this. dosome $ A + this. dosome $ B );
}
}}
From the code above, the internal class does not directly call the parameters passed in by the method, but the internal class backs up the parameters passed in to its own internal through its own constructor, the actual calling of your internal method is your own property rather than the parameters of the external class method.
In this way, we can easily figure out why we should use final, because the two seem to be the same thing in appearance, but they are not actually like this, if the internal class changes the values of these parameters, it cannot affect the original parameters, but the parameter consistency is lost because they are the same thing from the programmer's perspective, if the programmer changes the parameter value in the internal class during program design, but the value is not actually changed during external calls, it is very difficult to understand and accept, to avoid this embarrassing problem, the compiler designer sets the parameter that can be used by the internal class as final to avoid this inexplicable error.

Each process in JVM has multiple roots, each static variable, method parameter, and local variable. Of course, this is a guiding type. the basic type cannot be the root, but the root is actually a storage address. when the garbage collector is working, it first traverses the referenced objects from the root and marks them, so that the recursion is to the final end. After all the roots are traversed, the objects not marked are not referenced, objects that can be recycled (some objects have the finalized method, although not referenced, however, the JVM has a dedicated queue to reference them until the finalized method is executed, so it is not removed from the queue and can be recycled. This is irrelevant to the topic, including division of generation ). this looks good, but in the callback method of the internal class, S is neither a static variable nor a temporary variable in the method, nor a method parameter. It cannot be used as the root, in the internal class, there is no variable to reference it. In the method of its root outside the internal class, if the external variable s points to another object, the object s in the callback method loses the reference and may be recycled. Because most of the internal class callback methods are It is executed in the thread and may still be accessed after being recycled. What is the result? The use of the final modifier will not only ensure that the object reference will not change, but also the compiler will continue to maintain the lifecycle of this object in the callback method. therefore, this is the fundamental significance of final variables and final parameters.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.