[Go] Why the anonymous intrinsic class parameter must be of the final type

Source: Internet
Author: User

1) from the theory of programming language: The local inner class (i.e., the inner class defined in the method), because it is inside the method itself (can appear at the formal parameter definition or method body), thus accessing the method of local variables (formal parameters or local variables) is justified. It's natural.


2) Why add a restriction to Java: Only the final type local variables can be accessed?


3) The designer of the Java language compiler is of course fully implemented: The local inner class can access all local variables in the method (because: Theoretically this is a natural requirement), but: the compiler technology is not achievable or expensive.


4) Where is the difficulty?
The life cycle of the local variable is inconsistent with the life cycle of the local inner class object!


5) The method F is called to generate a variable i in its call stack, at which time a local inner class object Inner_object is generated, which accesses the local variable I. When the method F () runs, the local variable i is dead and does not exist. However: Local Inner class object Inner_ An object may also persist (it will only die if no one references the object again), and it will not end up dead with Method F (). At this point: there is a "ridiculous" result: the local inner class object Inner_object to access a nonexistent local variable i!


6) How can it be achieved? When the variable is final, the copy is directly used as a data member in the local interior by "copying" the final local variable. This way: when the internal class accesses local variables, it actually accesses the "replica" of the local variable (i.e.: This copy represents the local variable). Therefore: When the true local variable in the run stack dies, the local inner class object can still access the local variable (actually accessing the "replica"), giving the impression that the "lifetime" of the local variable is prolonged.


So: The core question is: How can we make: access to "replicas" and access to real original local variables, the semantic effect is the same?
When the variable is final, if the base data type, because its value is unchanged, thus: its copy is the same as the original amount. The semantic effect is the same. (if: Not final, there is no guarantee that the copy is consistent with the original variable because: the original variable is changed in the method, and the local inner class is replaced by a copy)

When a variable is final, a reference type, because its reference value is constant (that is, always pointing to the same object), and thus: its copy, like the original reference variable, always points to the same object (because it is final, thus guaranteeing: only point to this object, and then not to other objects), to achieve: Replicas accessed in the local inner class are always the same as the original objects accessed in the method code: The semantic effect is the same. Otherwise: When the original variable is changed in the method, and the local inner class is changed, there is no guarantee that the copy is consistent with the original variable (so: they should have been the same variable.)

Bottom line: The rule is a helpless one. It also shows that the design of programming language is limited by the implementation technology. This is one example. Because: I see a lot of people hold this view: design and ideas are the most important, the implementation of the technology is irrelevant, as long as you make the design and rules, can be achieved.



Now let's see if I want to implement an example that calls Absclass anonymously in a method:
public static void Test (final String s) {
or final String s = "Axman";
Absclass C = new Absclass () {
public void M () {
int x = S.hashcode ();

SYSTEM.OUT.PRINTLN (x);

}
};
Other code.
}

From the code point of view, the method of inner class defined inside a method to access local variables or method parameters inside an external method is very natural, but how to get this variable when the inner class compiles, because the inner class is a normal class in addition to its life cycle within the method. So how does the local variable or method parameter outside of it be accessed by the internal class? The compiler actually did this when it was implemented:


public static void Test (final String s) {
or final String s = "Axman";


Class Outerclass$1 extends absclass{

Private final String S;
Public outerclass$1 (String s) {
THIS.S = s;
}
public void M () {
int x = S.hashcode ();

SYSTEM.OUT.PRINTLN (x);

}
};

Absclass C = new outerclass$1 (s);
Other code.
}


That is, the variables of the outer class are passed to the private members of the inner class as arguments to the constructor method.
If there is no final, then:
public static void Test (String s) {
or string s = "Axman";
Absclass C = new Absclass () {
public void M () {
s = "other";
}
};
System.out.println (s);
}
will be compiled into:
public static void Test (String s) {
or string s = "Axman";

Class Outerclass$1 extends absclass{

Private String S;
Public outerclass$1 (String s) {
THIS.S = s;
}
public void M () {
s = "other";

}
};

Absclass C = new outerclass$1 (s);

}

The inner class's S re-pointing to "other" does not affect the parameter of test or the externally defined S. Similarly, if the external s re-assignment internal class s does not change.
And you see the
public static void Test (String s) {
or string s = "Axman";
Absclass C = new Absclass () {
public void M () {
s = "other";
}
};
System.out.println (s);
}

The syntax is a s, in the inner class has been changed, but the results printed out you think is the same s but still the original "Axman",
Can you accept such a result?
So final is syntactically constrained by the fact that two different variables are actually consistent (represented by the same variable).

[Go] Why the anonymous intrinsic class parameter must be of the final type

Related Article

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.