Deep analysis of the role of final keyword in Java programming _java

Source: Internet
Author: User
Tags inheritance modifier modifiers static class visibility

Final class
when a class is defined as final class, it means that the class cannot be inherited by other classes, that is, it cannot be used after extends. Otherwise, errors are obtained during compilation.

Package Com.iderzheng.finalkeyword;
 
Public final class Finalclass {
}
 
//Error:cannot inherit from final
class Packageclass extends Finalclass { c6/>}

Java support defines class as final, which seems to violate the basic principles of object-oriented programming, but on the other hand, closed classes ensure that all the methods of the class are fixed and that no subclass overrides are required to dynamically load. This provides more possibilities for the compiler to do optimizations, the best example being string, which is the final class, where the Java compiler can turn string constants (those contained in double quotes) directly into string objects, and directly optimize operator + operations to new constants. Because the final modification guarantees that no subclasses will return different values for the concatenation operation.
For all the different class definitions-the top-level class (Global or package visible), nested classes (inner classes or static nested classes) can be decorated with final. But generally final is used to decorate classes that are defined as global (public) because access modifiers have restricted their visibility to non-global classes, and it is difficult to inherit these classes without adding a final limit.

The other thing to mention is that anonymous classes (Anonymous Class), although they cannot be inherited, are not limited to final by the compiler.

Import Java.lang.reflect.Modifier;
 
public class Main {public
 
  static void Main (string[] args) {
    Runnable anonymous = new Runnable () {
      @Override 
   public void Run () {
      }
    };
 
    System.out.println (Modifier.isfinal (Anonymous.getclass (). getmodifiers ()));
  }

Output:

 False

Final method
closely related to the concept of inheritance is polymorphism (polymorphism), which involves a conceptual distinction between coverage (overriding) and concealment (hiding) (for convenience, the following are called "overrides" for these two concepts). However, unlike the method definition in C + +, whether a method with the virtual keyword affects the same method signature of a subclass is overridden or hidden. Overriding the parent class method with the same method signature in the Java lining class means that the class method (static method) is hidden, and the object method (Non-static method) occurs only as a result of overwriting. Because Java allows direct access to class methods through objects, Java does not allow the same signature of class methods and object methods in the same class.

The final class defines that the entire class cannot be inherited, and it also means that all methods in the class cannot be overwritten and hidden by the quilt class. When a class is not final decorated, some methods can still be decorated with final to prevent these methods from being overridden by quilts.

Similarly, such a design destroys object-oriented polymorphism, but the final method guarantees the certainty of its execution, thus ensuring the stability of the method invocation. Some of the implemented methods of abstract classes are often seen in some framework designs as being limited to final because some of the driver code in the framework relies on the implementation of these methods to accomplish the intended goal, so it is not desirable to have subclasses overwrite it.

The following example shows the role of the final modification in different types of methods:

Package com.iderzheng.other;
  public class Finalmethods {public static void Publicstaticmethod () {} public final void Publicfinalmethod () {
 
  public static final void Publicstaticfinalmethod () {} protected final void Protectedfinalmethod () {} Protected static final void Protectedstaticfinalmethod () {} final void Finalmethod () {} static final void S Taticfinalmethod () {} private static final void Privatestaticfinalmethod () {} private final void Privatefina
 
Lmethod () {}} package Com.iderzheng.finalkeyword;
 
Import Com.iderzheng.other.FinalMethods; public class Methods extends Finalmethods {public static void Publicstaticmethod () {}//Error:cannot Overrid E Public final void Publicfinalmethod () {}//Error:cannot override public static final void publicstaticfinal Method () {}//Error:cannot override protected final void Protectedfinalmethod () {}//Error:cannot over Ride ProtecteD static final void Protectedstaticfinalmethod () {} final void Finalmethod () {} static final void Staticfina  Lmethod () {} private static final void Privatestaticfinalmethod () {} private final void Privatefinalmethod ()
 {
  }
}

First of all, note that Finalmethods and methods are defined under different packages (package) in the above example. For the first Publicstaticmethod, the subclass succeeded in overriding the static method of the parent class, but because it is a static method, the occurrence is actually "hidden". The expression is that calling Methods.publicstaticmethod () performs the implementation in the methods class, and execution does not occur when the Finalmethods.publicstaticmethod () is invoked, but the implementation of the polymorphic load subclass is not occurring. Instead, it uses the Finalmethods implementation directly. So when you use subclasses to access methods, you hide the visibility of methods that have the same method signature as the parent class.
The global method Publicfinalmethod throws an exception at compile time by prohibiting the subclass from defining the same method to overwrite it as described in the final cosmetic method. However, it is possible to define the method name as a subclass, but with a parameter such as: Publicfinalmethod (String x), because this is the Synchronized method signature.

In IntelliJ, the IDE displays a warning to Publicstaticfinalmethod: ' static ' method declared ' final '. In its view this is superfluous, but it can be seen from the example that final also prohibits subclasses from defining the same static method to hide it. In actual development, the behavior of subclasses and parent classes that define the same static method is highly deprecated because the hidden method requires the developer to note that using different class name qualifiers can have different effects and can easily lead to errors. And, inside a class, you can call a static method without using the class name qualification, and the developer may not notice the hidden existence by default when you use the method of the parent class, you will find that it is not the expected result. So the static method should default to be final instead of hiding them, so the IDE thinks it is superfluous to modify.

The protected and public-decorated methods in the parent class are visible to subclasses, so the final modified protected method is the same as the public method. I would like to mention that the protected static method is rarely defined in actual development because the method is too low in practicality.

For the parent class package method, subclasses under different package are not visible, and private methods have been customized to be accessible only to the parent class. So the compiler allows subclasses to define the same method. This does not form overlay or hide, however, because the parent class has already hidden these methods by modifiers, rather than by the rewriting of subclasses. Of course, if the subclass and the parent class are under the same package, then the situation will be the same as the public, protected.

Why the final method is efficient:

The final method uses the embedded mechanism for inline optimization during the compilation process. Inline optimization refers to the direct invocation of function code substitution at compile time, rather than calling a function at run time. Inline needs to be compiled to know which function to use at the end, obviously, not final is not. Non-final methods may be overridden in subclasses, and because of the likelihood of polymorphism, the compiler cannot determine the true type of the object that will call the method in the compilation phase, and it cannot be sure which method is invoked.

Final Variable
simply put, the final variable in Java can only and must be initialized once, and then the variable is bound to that value. However, the assignment does not have to be initialized immediately when the variable is defined, and Java also supports different results for the final variable through conditional statements, except that the variable can only be assigned one time.

However, the final variable in Java is not an absolute constant, because the Java object variable is simply a reference value, so final only means that the reference cannot be changed, and the contents of the object can still be modified. Compared to the C + + pointer, it is more like the type * const variable than the type const * variable.

Java variables can be grouped into two categories: local variables (locally Variable), and class-member variables (classes Field). The following code is used to describe their initialization separately.

Local Variable

Local variables mainly refer to the variables defined in the method, and the methods they disappear are inaccessible. One particular case can be distinguished: the function argument. In this case, the initialization is bound to the parameters passed in when the function is invoked.

For other local variables, they are defined in the method, and their values can be initialized conditionally:

Public String Method (final Boolean Finalparam) {
  //error:final parameter Finalparam May is assigned
  /FINAL Param = true;
 
  Final Object finallocal = Finalparam? New Object (): null;
 
  final int finalvar;
  if (finallocal!= null) {
    Finalvar =;
  } else {
    Finalvar = 7;
  }
 
  Error:variable Finalvar might already have been assigned
  /Finalvar =
 
  Final String Finalret;
  Switch (finalvar) {case
    :
      Finalret = "Me";
      break;
    Case 7:
      Finalret = "she";
      break;
    Default:
      Finalret = null;
  }
 
  return finalret;
}

From the above example, it can be seen that the final modified function parameter cannot be given a new value, but other final local variables can be assigned in the conditional statement. This also provides a certain degree of flexibility to final.
Of course, all conditions in the conditional statement should contain an assignment to the final local variable, or you will get an error that the variable may not be initialized

Public String Method (final Object Finalparam) {
  final int finalvar;
  if (Finalparam!= null) {
    Finalvar =;
  }
 
  Final String Finalret;
 
  Error:variable Finalvar might not have been initialized
  switch (finalvar) {case
    :
      Finalret = "Me"; 
   
    break;
    Case 7:
      Finalret = "she";
      break;
 
  Error:variable Finalret might not have been initialized return
  Finalret;
}

   

In theory, local variables are not defined as final, and reasonably designed methods should be able to maintain local variables well. Only when you use anonymous functions in Java methods to do closures, Java requires that local variables that are referenced must be defined as final:

Public Runnable Method (string string) {
  int integer =;
  return new Runnable () {
    @Override the public
    Void Run () {
      //error:needs to be declared final
      System.out. println (string);
      Error:needs to is declared final
      System.out.println (integer);}}

Class Field

Class member variables can actually be divided into two types: static and non-static. For static class member variables, because they are related to a class, they can be placed in the static block, in addition to being initialized directly at the time of definition, and use the latter to execute more complex statements:

Package Com.iderzheng.finalkeyword;
 
Import Java.util.HashSet;
Import Java.util.LinkedHashSet;
Import Java.util.Set;
 
public class Staticfinalfields {
  static final int static_final_init_inline = 7;
  Static final set<integer> Static_final_init_static_block;
 
  /** static block **/
  static {
    if (System.currenttimemillis ()% 2 = 0) {
      Static_final_init_static_block = new Hashset<> ();
    } else {
      Static_final_init_static_block = new linkedhashset<> ();
    }
    Static_final_init_static_block.add (7);
    Static_final_init_static_block.add ();
  }

There are also non-static blocks in Java that can initialize non-static member variables, but for these variables more often are initialized in constructors (constructor). It is of course necessary to ensure that each final variable is initialized once in the constructor, and if other constructors are called through this (), the final variable cannot be assigned again in the constructor.

Package Com.iderzheng.finalkeyword;
 
public class Finalfields {
 
  final long final_init_inline = System.currenttimemillis ();
  Final long Final_init_block;
  Final long final_init_constructor;
 
  /** Initial block **/
  {
    final_init_block = System.nanotime ();
  }
 
  Finalfields () {This
    (217);
  }
 
  Finalfields (boolean bool) {
    final_init_constructor = 721;
  }
 
  Finalfields (Long init) {
    final_init_constructor = init;
  }
}

When final is used to modify classes (Class) and methods (method), it mainly affects the inheritance of object-oriented, without inheritance there is no subclass of the code dependencies on the parent, so in the maintenance of the code changes do not have to consider will not destroy the implementation of subclasses, it becomes more convenient. And when it is used on the variable (Variable), Java guaranteed that the variable value will not be modified, further design to ensure that the members of the class can not be modified, then the entire variable can become constant use, for multithreaded programming is very advantageous. So final has a very good effect on code maintenance.

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.