Again, the Java final variable

Source: Internet
Author: User

http://blog.csdn.net/axman/article/details/1460544 from jdk1.0 to today, Java technology has undergone a great change in technology over the past more than 10 years. But the final variable is defined from its
Since the day of birth, there has been no change, that is, for the past more than 10 years it has been the meaning of its original.

Unfortunately, after more than 10 years still 90% of people do not understand its true meaning, nor an article, including all the introductions I have seen
Java books (including tkj) are not clear, I am sure some writers are understandable, but not one author to the reader clear. and the Chinese netizens
Most people are a nonsense << talking about the final,finalized,finally>> article in Java running across the horse. (Blush: I did, too).

The definition of the final variable itself is not complex, that is, once the variable is initialized, it can no longer point to other objects. In C + + it is a const pointer, and
Instead of a pointer to a const variable, the const pointer means that it can only point to the address at initialization. But the object itself in that address
can be modified. A pointer to a const variable means that the object itself cannot be modified.

such as: final StringBuffer sb = new StringBuffer ("Axman");
SB = new StringBuffer ("Sager");//error, SB can no longer point to other objects.
Sb.append ("was changed!"); SB-pointed ground like itself can be modified.

First, the final variable is initialized:

Many articles say this: its initialization can be in two places, one is its definition, and the other is in the constructor, the two can only be selected.
Nonsense!
The final variable can be initialized in any place that can be started, but only once. Once initialized, it cannot be assigned again.
Value (re-pointing to other objects), must be explicitly initialized as a member variable, and as a temporary variable you can define not initialize (and of course not)
Even as a member variable in a class, it can also be initialized in the initialization block, so "its initialization can be in two places, one is its definition,
Second, in the constructor, the two can only choose one "is wrong.


As a member variable, the final field can be designed with immutable classes, which is a necessary condition for the invariant class, but not a sufficient condition. At a minimum, you can guarantee that the field is not
Will change in such a way as setxxx (). But there is no guarantee that the field itself is not modified (unless the field itself is a constant class);

For the final variable of the method parameter:
For a variable of a method parameter defined as final,90%, the article says "When you do not need to change an object variable as a parameter in the method, explicitly make the
Declaring with final will prevent you from inadvertently modifying variables that are outside of the calling method. "
Nonsense!

I don't know if this change is about re-assigning or modifying the object itself, but in either case, the above statement is wrong.
If you are saying re-assignment, then:
public static void Test (int[] x) {
x = new int[]{1,2,3};
}

Int[] out = new int[]{4,5,6};
Test (out);
System.out.println (Out[0]);
System.out.println (out[1]);
System.out.println (out[2]);
Call test (out); it does not affect the outside variable out anyway. It doesn't make any sense to add to your final. Final will only force the inside of the method
Declare a variable name, that is, x = new int[]{1,2,3}, and change to int y = new int[]{1,2,3}; The other does not have any practical significance.
If you are modifying the object itself:
public static void Test (final int[] x) {
X[0] = 100;
}
Int[] out = new int[]{4,5,6};
Test (out);
System.out.println (Out[0]);
Can't you modify it with the final decoration? So it's nonsense to say that final in the method parameter is not affecting variables outside of the calling method.

So why do we have to add final to the parameters? In fact, the method parameter plus final and method internal variables plus final function is the same, that is, in order to put them
Guaranteed invocation consistency when passed to an inner class:

Abstract class absclass{
public abstract void M ();
}

Now let's see if I want to implement an anonymous call to Absclass in a method. Should:
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).

Again, the Java final variable

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.