Talk aboutfinal Keyword, I think many people are familiar, Often used when using anonymous inner classesfinal Keyword. in addition,Java MediumString Class is afinal class, So let's get to know todayfinal Usage of this keyword.

One,final Basic usage of keywords

stayJava in,final Keywords can be used to decorate classes, Methods and variables( Include member and local variables). Let's take a look at these three aspectsfinal Basic usage of keywords.

1, Modification class

   When usedfinal When modifying a class, Indicates that this class cannot be inherited. In other words, If a class you will never let it be inherited, You can use it.final Modify.
final Member variables in a class can be set tofinal, But pay attentionfinal All member methods in a class are implicitly specified asfinal Method.



in usefinal When modifying a class, Careful choice, Unless the class is really not used for inheritance or security, Try not to design classes asfinal class.

2, Modification method

     Here's an excerpt from《Java Programming idea》 The Fourth Edition143 page:

 
“ Usefinal There are two reasons for this approach. The first reason is to lock the method, To prevent any inherited class from modifying its meaning; The second reason is efficiency. EarlyJava In implementation version, Willfinal Method to inline call. But if the method is too large, You may not see any performance gains from embedded calls. RecentJava Version, No need to usefinal Methods are optimized.“

   therefore, If you're just trying to make it clear This method is only set to when it is overridden in a subclassfinal Of.
Parent classfinal Methods cannot be overridden by subclasses, That is to say, subclasses can not be exactly the same as the parent class..

     final Decorated method indicates that the method is already“ Final, Final” Meaning, That is, this method cannot be overridden( Can overload multiplefinal The method of decoration).
One thing to note here is: Because the overriding premise is that the subclass can relay this method from the parent class, If the parent classfinal The decorated method and access control permission areprivate,
This will result in the subclass cannot inherit this method directly, therefore, In this case, you can define the same method name and parameter in the subclass, Rewriting andfinal Contradictions, It redefines new methods in subclasses.
( notes: Classprivate Method is implicitly specified asfinal Method.)
public class B extends A { public static void main(String[] args) { } public
void getName() { } } class A { /** *
becauseprivate Modification, Cannot inherit this method in subclass, therefore, SubclassgetName Method is redefined, * Methods belonging to subclass itself, Compile normal*/ private final
void getName() { } /* becausepblic Modification, Subclasses can inherit this method, Results in overriding thefinal Method, Compile error public final
void getName() { }*/ }
 3, Modifier variable
      The modifier variable isfinal Most used places, It is also the content that this article will focus on next.

      final Member variables represent constants, Can only be assigned once, The value will not change after assignment.

   Whenfinal When decorating a basic data type, Indicates that the value of the basic data type cannot change once it is initialized;
Iffinal When decorating a reference type, After it is initialized, it can no longer point to other objects, But the content of the object that this reference points to can change.
It's essentially the same thing, Because the reference value is an address,final Required value, That is, the value of the address does not change.

  final Decorate a member variable( attribute), Initialization must be displayed. There are two initialization methods
, One is initialization when variables are declared; The second method is to declare variables without initial values, But you need to assign an initial value to this variable in all constructors of the class in which it resides.

   When the parameter type of a function is declared asfinal Time, Indicates that the parameter is read-only. That is, you can read and use this parameter, But the value of the parameter cannot be changed.

       For instance:



     In the code above, Pair variablesi andobj The reassignment of is wrong.

Two, Deep understandingfinal Keyword

Got it.final After basic usage of keyword, Let's take a look at this sectionfinal Where keywords are confusing.

1, Classfinal What's the difference between variables and common variables?

    
When usedfinal When acting on a member variable of a class, Member variables( Note that it is a member variable of the class, Local variables only need to be initialized and assigned before use) Must be initialized at definition time or in the constructor, Andfinal Once the variable is initialized and assigned, Can't be assigned any more.

     thatfinal What's the difference between variables and common variables? Here is an 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
    
You can think about the output of this question first. Why is the first comparisontrue, The second comparison isfasle. Here it isfinal The difference between variable and common variable, Whenfinal Variables are basic data types andString Type time, If you know its exact value during compilation, The compiler will use it as a compile time constant. That is to say, when using thefinal Variable place, The constant equivalent to direct access, Does not need to be determined at run time. Such sumC Macro replacement in language is a bit like. So in the code above, Due to variablesb coverfinal Modification, So it's treated as a compiler constant, So in the use ofb Where the variablesb
Replace with its value. And for variablesd But it needs to be linked at run time. I think you should understand the difference, But pay attention,
Only during compilation can we know for surefinal In case of variable value, That's what the compiler does, For example, the following code will not be optimized:
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 isfalse.
One thing to note here is that: Don't think some of the data isfinal You can know its value at compile time, By variablesb We'll see, Here is the use ofgetHello() Method to initialize it, He needs to be in operation to know its value.

2, coverfinal Does the decorated reference variable point to a variable object?

Mentioned above byfinal Once the modified reference variable initializes the assignment, it can no longer point to other objects, Is the content of the object pointed to by the reference variable variable? Here's an example:
public class Test { public static void main(String[] args) { final MyClass
myClass =new MyClass(); System.out.println(++myClass.i); } } class MyClass {
public int i = 0; }
This code can be compiled successfully and output results are available, The output is1. This means that the reference variable isfinal After modification, Although it can no longer point to other objects, But the content of the object it points to is variable.

3,final Parameter problems

     in application, We can usefinal Decorate member variables, Member method, class, You can also modify parameters, If a parameter isfinal Decorated, It means that 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
be blank and not using a compound assignment. See 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 Parameters cannot be changed //
i++; System.out.println(i); } }

The above codechangeValue Parameters in methodi usefinal After modification, You cannot change variables in methodsi It's worth it.. A point worth noting, MethodchangeValue andmain Variable in methodi It's not a variable at all, becausejava Parameter passing adopts value passing, For variables of basic type, Equivalent to copying variables directly. So even if notfinal In the case of decoration, Variable changed inside methodi The value of does not affect the value ofi.

Look at the following code again:
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 Decorate parameters of reference types, It can no longer point to other objects, But you can change what it points to.//buffer = new StringBuffer("hi");
buffer.append("world"); } }
Run this code and you will find that the output is
helloworld. Obviously, usefinal You can't let it gobuffer Point to other objects, But forbuffer The content of the pointed object can be changed. Now suppose a situation, If putfinal Remove, What will happen? Look at the code below:
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 Point to another object again buffer = new
StringBuffer("hi"); buffer.append("world"); System.out.println(buffer); } }
Operation result:
hiworld hello
From the operation results, we can see that, takefinal After removing, At the same timechangeValue Medium yieldbuffer Pointed to other objects, It doesn't affectmain Method inbuffer,
The reason lies injava Value passing is used, For reference variables, The value of the reference is passed, That is to say, let the actual parameter and the formal parameter point to the same object at the same time, So having a parameter point back to another object has no effect on the argument.