When it comes to the final keyword, it's probably a lot of people who are not unfamiliar with the final keyword when using anonymous internal classes. In addition, the string class in Java is a final class, so today we'll look at the use of the final keyword.
First, the basic usage of final key words
In Java, the final keyword can be used to decorate classes, methods, and variables (including member variables and local variables). Here's a look at the basic usage of the final keyword in three ways.
1. Decoration class
When a class is decorated with final, it indicates that the class cannot be inherited. In other words, if a class you never let him inherit, you can use final to decorate. Member variables in the final class can be set to final as needed, but note that all member methods in the final class are implicitly specified as the final method.
When using the final modifier class, be careful to choose, unless the class is not intended to be inherited later or for security reasons, try not to design the class as the final class.
2. Modification method
The following is part of the fourth edition of Java Programming thought, page 143th:
There are two reasons for using the final method. The first reason is to lock the method in case any inherited class modifies its meaning, and the second reason is efficiency. In earlier versions of Java implementations, the final method was converted to inline invocation. However, if the method is too large, you may not see any performance gains from inline calls. In the recent Java release, these optimizations do not need to be made using the final method. “
Therefore, the method is set to final only if you want to explicitly prohibit the method from being overwritten in the subclass. That is, the final method of the parent class is not covered by the quilt class, that is, the subclass is not able to exist the same way as the parent class.
The final decorated method means that this method is already a "final, final" meaning, that is, this method cannot be overridden (you can overload multiple final-decorated methods). One thing to note here is that because the overriding premise is that subclasses can inherit this method from the parent class, if the final decorated method in the parent class has access control permissions of private, it will cause the subclass not to inherit directly into this method, so you can define the same method name and parameter in the subclass. Instead of having to rewrite the final contradiction, the new method is redefined in the subclass. (Note: The private method of the class is implicitly specified as the final method.) )
public class B extends a {public static void Main (string[] args) { } public void GetName () { }}class A { c5/>/** * Because of the private adornment, the subclass cannot inherit this method, so the GetName method in the subclass is a redefined, * method that belongs to the subclass itself, compiled normally */ private final void GetName () { }/ * Because Pblic is decorated, subclasses can inherit to this method, resulting in overriding the final method of the parent class, compilation error public final void GetName () { } */}
3. Modifier variables
The modified variable is the most used place in final use, and it is also the focus of this article.
The final member variable represents a constant, which can only be assigned once, and the value will no longer change after the value is assigned.
When final modifies a base data type, the value that represents the base data type cannot change after initialization, and if final decorates a reference type, it cannot point to another object after it is initialized, but the contents of the object pointed to by the reference can vary. is essentially one thing, because the value of the reference is an address, the final requirement value, that is, the value of the address does not change.
final modifies a member variable (property) that must be displayed for initialization. There are two types of initialization , one is initialized at the time of the variable declaration, and the second is to not assign the initial value when declaring the variable, but to assign an initial value to the variable in all the constructors of the class where the variable resides.
When the parameter type of a function is declared final, the parameter is read-only. That is, you can read it using this parameter, but you cannot change the value of the parameter.
As an example:
In the above section of the code, the re-assignment of the variables I and obj is an error.
Second, in-depth understanding of the final keyword
After understanding the basic usage of the final keyword, let's look at where the final keyword is easy to confuse.
1. What is the difference between a class's final variable and a normal variable?
When you use final action on a member variable of a class, the member variable (note is the member variable of the class, the local variable needs to be guaranteed to be initialized before use) must be assigned in the definition or constructor, and once the final variable is initialized, it can no longer be assigned a value.
So what is the difference between a final variable and a normal variable? Let's take a look at the following example:
public class Test {public static void Main (string[] args) { String a = "Hello2"; Final String b = "Hello"; String d = "Hello"; String C = b + 2; String E = d + 2; System.out.println ((A = = c)); System.out.println ((A = = e));
Output result: true, False
We can first think about the output of this problem. Why the first comparison result is true, and the second compares the result to Fasle. This is the difference between the final variable and the normal variable, when the final variable is the base data type and the string type, if you can know its exact value during compilation, the compiler will use it as a compile-time constant. That is, where the final variable is used, it is equivalent to the constant that is accessed directly, and does not need to be determined at run time. This is a bit like a macro substitution in C language. So in the preceding section of code, because the variable B is final decorated, it is treated as a compiler constant, so where B is used, the variable b is replaced directly with its value. The access to variable D needs to be linked at run time. Presumably the difference should be understood, but note that the compiler does this only if the final variable value is known exactly during compilation, as the following code does not optimize:
public class Test {public static void Main (string[] args) { String a = "Hello2"; Final String B = Gethello (); String C = b + 2; System.out.println ((A = = c)); } public static String Gethello () { return "Hello";
The output of this code is false. One thing to note here is this: don't assume that some data is final and you know its value at compile time, and with variable b we know that it's initialized with the Gethello () method, and he's going to know its value at run time.
2. Is the object content of the final modified reference variable variable?
In the above mentioned the final modified reference variable once the initialization of the assignment can no longer point to other objects, then the reference variable point to the contents of the object is variable? Look at the following example:
public class Test {public static void Main (string[] args) { final MyClass MyClass = new MyClass (); System.out.println (++MYCLASS.I); } } class MyClass {
This code can be successfully compiled and has output results, the output is 1. This means that after the reference variable is final decorated, it cannot point to another object, but the contents of the object it points to are mutable.
3, final parameters of the problem
In practice, we can modify a member variable, a member method, a class, or a parameter, if a parameter is final, in addition to the final modifier, which means the parameter is immutable. If we modify this parameter in the method, the compiler will prompt you: The final local variable I cannot be assigned. It must is blank and not using a compound assignment. Look at the following example:
public class Testfinal {public static void Main (string[] args) { testfinal testfinal = new testfinal (); int i = 0; Testfinal.changevalue (i); System.out.println (i); } public void ChangeValue (final int i) { //final parameter cannot be changed //i++; System.out.println (i); }}
The value of the variable I cannot be changed in the method after the above code changevalue the parameter I in the method with the final decoration. It is worth noting that the method changevalue and the variable I in the Main method are not a variable at all, because the Java parameter pass takes the value pass, and for the basic type of variable, it is equivalent to copying the variable directly. So even without final modification, changing the value of the variable I within the method does not affect the I outside of the method.
Let's look at the following code:
public class Testfinal {public static void Main (string[] args) { testfinal testfinal = new testfinal (); StringBuffer buffer = new StringBuffer ("Hello"); Testfinal.changevalue (buffer); SYSTEM.OUT.PRINTLN (buffer); } public void ChangeValue (final stringbuffer buffer) { //final modifies a parameter of a reference type and can no longer point it to another object, but the content to which it points is subject to change. //buffer = new StringBuffer ("HI"); Buffer.append ("World");} }
Running this code will reveal that the output is HelloWorld. It is clear that the final modification can no longer allow buffer to point to other objects, but the contents of the object to which buffer points are changed. Now suppose a situation, if final is removed, what will the result be? Look at the following code:
public class Testfinal {public static void Main (string[] args) { testfinal testfinal = new testfinal (); StringBuffer buffer = new StringBuffer ("Hello"); Testfinal.changevalue (buffer); SYSTEM.OUT.PRINTLN (buffer); } public void ChangeValue (StringBuffer buffer) { //buffer re-points to another object, buffer = new StringBuffer ("HI"); Buffer.append ("World"); SYSTEM.OUT.PRINTLN (buffer);} }
Operation Result:
Hiworldhello
As can be seen from the running results, the final is removed, and in the ChangeValue buffer points to other objects, and does not affect the buffer in the main method, because Java is the value of the pass, for the reference variable, passed the reference value, This means that the argument and the parameter point to the same object at the same time, so having the parameter point back to another object has no effect on the argument.
Talking about the final keyword in Java