Final keyword usage examples in Java _java

Source: Internet
Author: User
Tags arrays rand


This example describes the final keyword usage in java. Share to everyone for your reference, specific as follows:



Depending on the context, the Java keyword Final also has a subtle distinction, but it usually means "this is immutable." "There are two reasons not to change: one is efficiency, the other is design." Due to the fact that two reasons are far away, the key final may be misused.



Next, I'll introduce you to the final three: data, methods, classes



Final data



Many programming languages have some way of telling the compiler that a piece of data is immutable. Sometimes the constant invariant of data is useful, for example:



1. A constant at compile time constant
2. One initializes at runtime, and you do not want it to be changed.



For this case of a compile-time constant, the compiler can substitute the constant value in any formula that might be used in it, that is, the formula can be executed at compile time, which alleviates some of the run-time burden. In Java, such constants must be of the base type and expressed in final. When you define this constant, you must assign a value.



A domain that is static and final is only a storage space that cannot be changed.



When final is applied to an object reference, rather than the base type, its meaning is somewhat confusing. The final change to the base type is his value. For an object reference, the reference cannot be changed, and the object itself can be modified. Once a final reference is initialized to point to an object, the reference cannot be directed at another object. Java does not provide a constant support for any object. This restriction is also applicable to arrays, and it is also an object. For example:

package finalPackage;
import java.util. *;
class Value {
  int i;
  public Value (int i) {
    this.i = i;
  }
}
/ **
 * final data constant
 * @author Administrator
 * What can't be changed with the basic type is its value.
 * For the object reference, what can not be changed is his reference, and the object itself can be modified.
 * Once a final reference is initialized to point to an object, the reference will not be able to point to other objects.
 * Note that, according to the convention, domains that are static and final (that is, compiler constants) will be represented in uppercase and separated by underscores.
 * /
public class FinalData {
  private static Random rand = new Random (47);
  private String id;
  public FinalData (String id) {
    this.id = id;
  }
  // Can be compile-time constants:
  private final int valueOne = 9;
  private static final int VALUE_TWO = 99;
  // Typical public constant:
  public static final int VALUE_THREE = 39;
  // Cannot be compile-time constants:
  private final int i4 = rand.nextInt (20);
  static final int INT_5 = rand.nextInt (20);
  private Value v1 = new Value (11);
  private final Value v2 = new Value (22);
  private static final Value VAL_3 = new Value (33);
  // Arrays:
  private final int [] a = {1, 2, 3, 4, 5, 6};
  public String toString () {
    return id + ":" + "i4 =" + i4 + ", INT_5 =" + INT_5;
  }
  public static void main (String [] args) {
    FinalData fd1 = new FinalData ("fd1");
    //! fd1.valueOne ++; // Error: can't change value
    fd1.v2.i ++; // Object isn't constant!
    fd1.v1 = new Value (9); // OK-not final
    for (int i = 0; i <fd1.a.length; i ++)
      fd1.a [i] ++; // Object isn't constant!
    //! fd1.v2 = new Value (0); // Error: Can't
    //! fd1.VAL_3 = new Value (1); // change reference
    //! fd1.a = new int [3];
    System.out.println (fd1);
    System.out.println ("Creating new FinalData");
    FinalData fd2 = new FinalData ("fd2");
    System.out.println (fd1);
    System.out.println (fd2);
  }
  / **
   * Output result:
   * fd1: i4 = 15, INT_5 = 18
   * Creating new FinalData
   * fd1: i4 = 15, INT_5 = 18
   * fd2: i4 = 13, INT_5 = 18
   * /
}

Since valueOne and VALUE_TWO are final basic types with compile-time values, both of them can be used as compile-time constants, and there is no significant difference. VALUE_THREE is a more typical way to define constants: defined as public, can be accessed by anyone; defined as static, it emphasizes that there is only one; defined as final, which shows that it is a constant. Please note that the final static basic types with constant initial values are all named with capital letters, and the letters are separated by underscores.

We can't think that because some data is final, we can know its value at compile time. The use of random numbers to initialize the values of i4 and INT_5 at runtime illustrates this point. In the example, the values of i4 in fd1 and fd2 are unique and will be initialized to 15,13 each time. The value of INT_5 cannot be changed by creating a second FinalData object. This is because it is static, and has been initialized when loading the class (that is, when this class object is first created), rather than initialized every time it is created.

Java may generate "blank final". The so-called blank final refers to the field declared as final but not given the initial value. In any case, the compiler will ensure that the final field is initialized before use. However, blank final provides great flexibility in the use of final. For this reason, a final field can be different according to some objects, but it remains constant. The following example illustrates one point:

package finalPackage;
class Poppet {
  private int i;
  Poppet (int ii) {
    i = ii;
  }
  public int getI () {
    return i;
  }
  public void setI (int i) {
    this.i = i;
  }
}
/ **
 * Blank final
 * @author Administrator
 * The so-called blank final refers to the field declared as final but not given an initial value. In any case, the compiler will ensure that the final field is initialized before use.
 * /
public class BlankFinal {
  private final int i = 0; // Initialized final
  private final int j; // Blank final
  private final Poppet p; // Blank final reference
  // Blank finals MUST be initialized in the constructor:
  public BlankFinal () {
    j = 1; // Initialize blank final
    p = new Poppet (1); // Initialize blank final reference
  }
  public BlankFinal (int x) {
    j = x; // Initialize blank final
    p = new Poppet (x); // Initialize blank final reference
  }
  public static void main (String [] args) {
    BlankFinal b1 = new BlankFinal ();
    BlankFinal b2 = new BlankFinal (47);
    System.out.println ("b1.j =" + b1.j + "\ t \ t b1.p.i =" + b1.p.getI ());
    System.out.println ("b2.j =" + b2.j + "\ t \ t b2.p.i =" + b2.p.getI ());
  }
  / **
   * Output result:
   * b1.j = 1 b1.p.i = 1
   * b2.j = 47 b2.p.i = 47
   * /
}

final parameter

In Java, the parameters in the parameter list may be declared final in a declarative manner. This means that you never change the object pointed to by the parameter. E.g:

package finalPackage;
class Gizmo {
  public void spin (String temp) {
    System.out.println (temp + "Method call Gizmo.spin ()");
  }
}
/ **
 * final parameter
 * @author Administrator
 * If the parameter in the parameter list is specified as final, it means that you never change the reference of the object pointed to by the parameter.
 * /
public class FinalArguments {
  void with (final Gizmo g) {
    //! g = new Gizmo (); // Illegal-g is final
  }
  void without (Gizmo g) {
    g = new Gizmo (); // OK-g not final
    g.spin ("without");
  }
  // void f (final int i) {i ++;} // Can't change
  // You can only read from a final primitive:
  int g (final int i) {
    return i + 1;
  }
  public static void main (String [] args) {
    FinalArguments bf = new FinalArguments ();
    bf.without (null);
    bf.with (null);
    System.out.println ("bf.g (10) =" + bf.g (10));
  }
  / **
   * Output result:
   * withoutMethod call Gizmo.spin ()
   * bf.g (10) = 11
   * /
}

There are two reasons for using the final method. The first reason is to lock the method to prevent any class inheriting it from modifying its meaning. This is for design considerations: you want to ensure that the methods used in inheritance remain the same and will not be overwritten.

The second reason why the final method was recommended in the past was efficiency. In the early implementation of java, if a method is specified as final, it is agreed that the compiler will convert all calls to this method into inline calls. When the compiler finds a final method call command, it will execute the method call mechanism by skipping the normal call method of inserting program code according to its own cautious judgment (push the parameter onto the stack, jump to the method code to execute, and then Jump back and clean the parameters in the stack, process the return value), and replace the method call with a copy of the actual code in the method body. This will eliminate the overhead of method invocation. Of course, if a method is large, your program code will swell, so you may not see the performance improvement brought by embedding, because the performance will be reduced by the amount of time spent in the method.

In the recent Java version, the virtual machine (especially hotspot technology) can detect these situations and optimize to remove these additional embedded calls that have reduced efficiency, so there is no need to use the final method to optimize. In fact, this approach is gradually being discouraged. When using java se5 / 6, you should let the compiler and JVM deal with the efficiency problem. Only when you want to explicitly prohibit overwriting, set the method to final.

final and private keywords

All private methods in the class are implicitly made final. Since you cannot access the private method, you cannot overwrite it. You can add final modification to the private method Word, but it makes no sense. E.g:

package finalPackage;
/ **
 * final and private keywords
 *
 * All private methods in the class are implicitly made final.
 * Since you cannot access the private method, you cannot overwrite it.
 * The final modifier can be added to the private method, but this is meaningless.
 * /
class WithFinals {
  // Identical to "private" alone:
  private final void f () {
    System.out.println ("WithFinals.f ()");
  }
  // Also automatically "final":
  private void g () {
    System.out.println ("WithFinals.g ()");
  }
}
class OverridingPrivate extends WithFinals {
  private final void f () {
    System.out.println ("OverridingPrivate.f ()");
  }
  private void g () {
    System.out.println ("OverridingPrivate.g ()");
  }
}
class OverridingPrivate2 extends OverridingPrivate {
  public final void f () {
    System.out.println ("OverridingPrivate2.f ()");
  }
  public void g () {
    System.out.println ("OverridingPrivate2.g ()");
  }
}
public class OverideFinal {
  public static void main (String [] args) {
    WithFinals w1 = new WithFinals ();
    //! w1.f (); // Error, cannot access private method
    //! w1.g (); // Error, unable to access private method
    OverridingPrivate w2 = new OverridingPrivate ();
    //! w2.f (); // Error, unable to access private method
    //! w2.g (); // Error, cannot access private method
    OverridingPrivate2 w3 = new OverridingPrivate2 ();
    w3.f ();
    w3.g ();
  }
  / **
   * Output result:
   * OverridingPrivate2.f ()
   * OverridingPrivate2.g ()
   * /
}

"Override" only occurs when a method is part of the base class interface. That is, you must transform an object up to its base class and call the same method. If a method is private, it is not part of the base class interface. It is just some program code hidden in the class. If a private method exists in a base class, create a public, protected or package access method with the same name in the derived class. This method is nothing more than the base The methods in the class have the same name, and do not override the base class methods. Since the private method cannot be touched and can be effectively hidden, it does not need to be considered for anything except that it exists because of the organizational structure of the class to which it belongs.

final class

When the class is defined as final, it shows that you do not intend to inherit the class, and do not allow others to do so. In other words, for some considerations, you never need to make any changes to the design of this class, or for security reasons, you do not want him to have subclasses. E.g:

package finalPackage;
class SmallBrain {
}
final class Dinosaur {
  int i = 7;
  int j = 1;
  SmallBrain x = new SmallBrain ();
  void f () {
    System.out.println ("Dinosaur.f ()");
  }
}
//! class Further extends Dinosaur {}
// error: Cannot extend final class 'Dinosaur'
/ **
 * final class
 *
 * The attributes in the final class can be optionally defined as final
 * The methods in the final class are implicitly formulated as final methods, so you cannot override them
 * /
public class Jurassic {
  public static void main (String [] args) {
    Dinosaur n = new Dinosaur ();
    n.f ();
    n.i = 40;
    n.j ++;
    System.out.println ("n.i =" + n.i);
    System.out.println ("n.j =" + n.j);
  }
  / **
   * The output result is:
   * Dinosaur.f ()
   * n.i = 40
   * n.j = 2
   * /
}

Please note that the domain of the final class can choose to be final or not according to personal wishes. Regardless of whether the class is defined as final, the same rules apply to domains defined as final. However, because final cannot be inherited, the methods in the class modified by final are implicitly formulated as fianl because you cannot override them. In the fianl class you can add final to the method, but this will not make any sense.

in conclusion:

According to the context of the program, the Java keyword final has the meaning of "this cannot be changed" or "final", and it can modify non-abstract classes, non-abstract class member methods and variables. You may need to prevent change for two reasons: design or efficiency.
The final class cannot be inherited and has no subclasses. The methods in the final class are final by default.
Final methods cannot be overridden by subclass methods, but can be inherited.
The final member variable represents a constant and can only be assigned once, and the value will not change after the assignment.
final cannot be used to modify the construction method.
Note: The private member methods of the parent class cannot be overridden by subclass methods, so private type methods are final by default.

Hope this article is helpful to everyone in Java programming.

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.