The JAVA keyword final is used to modify data, methods or classes, which usually means "unchangeable", that is, data cannot be changed, methods cannot be overridden, and classes cannot be inherited. There are generally two reasons for using final: design and efficiency. As the JAVA version is updated, some efficiency issues can be handled by the compiler and JVM. Therefore, using final to solve efficiency problems is not so important.
The Final modifier is mostly used in the fields of primitive data types or immutable classes (if all methods in the class will not change its object, this class is an immutable class. String is an immutable class ).
【final data】
There are two main situations in which the Final keyword is used to modify data:
1. Compile-time constants
2. Values initialized at runtime
For compile-time constants, it refers to a field that is both final and static (according to convention, compile-time constants are named with all capital letters, and each word is separated by an underscore). It only occupies a storage space that cannot be changed. The compiler can substitute compile-time constants into any calculation formula that may use it. That is to say, the calculation formula can be executed at compile time, which relatively reduces the runtime burden. A compile-time constant must have a value assigned to it when it is defined (not necessarily a basic type).
For values initialized at runtime, for basic types, final makes the value unchangeable; for object references, final makes the reference unchangeable, that is, it cannot be changed to point to another object. However, the object itself can be modified (applicable to arrays , arrays are also objects).
private static final String TESTD = "test";
public static final String TESTE = "test";
public static final String[] TESTF = {"1","2"}; //Non-basic type
private static final String[] TESTG = new String[2];
public static void main(String args[]){
final int testA = 1;
final String testB = "test";
final int[] testC = {1,1,2,};
System.out.println(testC[1]);
testC[1] = 123;
System.out.println(testC[1]);
}
}
JAVA allows the generation of unassigned final fields, but the final field must be assigned at the definition of the field or in each constructor (as many constructors as there are) to ensure that it is initialized before use. In this way, final can be used more flexibly. In the same class, different values can be assigned to different objects while maintaining immutable characteristics.
public javaBlankFinal(){
blank = 2011;
}
public javaBlankFinal(int temp){
blank = 2012;
}
public javaBlankFinal(String temp){
blank = 2014;
}
public static void main(String args[]){
new javaBlankFinal();
}
}
There are two reasons for using the final method: one is to lock the method to prevent the method from being overwritten and ensure that the method behavior remains unchanged during inheritance; the other is to convert method calls into inlining calls to reduce the cost of method calls. However, in recent versions, the JVM can optimize itself, so there is no need to use final methods to deal with efficiency issues.
Regarding the final method, there is another thing to note. All private methods in the class are implicitly designated as final methods (you can also add final modification to them, but it is meaningless). When you try to override a private method, the compiler does not report an error, but in fact you do not overwrite the method, you just generate a new method. Because the private method cannot be accessed by external classes, of course it cannot be overridden.
Using the @Override annotation can prevent the above problems. As shown in the program:
private final void finalFunctionB(){
System.out.println("finalFunctionB");
}
final void finalFunctionC(){
System.out.println("finalFunctionC");
}
void functionD(){}
}
class overrideFinalFunction extends finalFunction{
//@Override Add the @Override annotation to identify whether it is an override
public void finalFunctionA(){
System.out.println("override finalFunctionA");
}
public final void finalFunctionB(){
System.out.println("override finalFunctionB");
}
//final void finalFunctionC(){} //Cannot override the final method from finalFunction
@Override
void functionD(){} //Real override method
}
public class javaFinalFunction extends finalFunction{
public static void main(String args[]){
finalFunction ff = new finalFunction();
//ff.finalFunctionA(); //Cannot call private method
//ff.finalFunctionB();
overrideFinalFunction off = new overrideFinalFunction();
off.finalFunctionA(); //public method
off.finalFunctionB();
}
}
The use of final classes is generally for design reasons, which do not allow the class to be inherited. This ensures that the behavior of the class will not change, and may also avoid some security risks. All methods in the Final class are implicitly designated as final methods and therefore cannot be overridden (because the final class prohibits inheritance, methods in its class cannot be overridden). In the Java core API, there are many examples of applying final, such as java.lang.String. Specify final for the String class to prevent overwriting methods such as length().
For final fields, even if a class is declared final, the fields in the class will not automatically become final fields.
public class javaFinalClass{
public static void main(String args[]){
finalClass fc = new finalClass();
System.out.println(fc.testA);
fc.testA = 2012;
System.out.println(fc.testA);
}
}