[Java] Final keyword

Source: Internet
Author: User

Depending on the context, there are subtle differences in the Java keyword final, but it usually means "this cannot be changed." "There are two reasons why you don't want to change: one is efficiency, the other is design. Because there are two different reasons for the difference, the key sub-final may be used by Wu.

Next, let's look at the three scenarios used in FIANL: data, methods, classes.



Final data

Many programming languages have a way to tell the compiler that a piece of data is constant. Sometimes it is useful to have constant data, for example:

1, a constant at compile time constant

2, one is initialized at run time, and you don't want it to be changed.

In this case of a compile-time constant, the compiler can substitute the constant value into any calculation that might be used in it, that is, the calculation can be performed at compile time, which relieves some of the runtime's burden. In Java, such constants must be of the basic type and are represented in the final. When you define this constant, you must assign a value.

A domain that is static and fianl occupies 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 use of fianl for a basic type cannot be changed by 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 an object, the reference cannot point to another object. Java does not provide constant support for any object. This restriction is also common for arrays, which are also objects.

The following example demonstrates the case of a fianl domain. Note that, according to the Convention, a field that is static and fianl (that is, compiler constants) is represented in uppercase and divided by the following words:

[Java] View plaincopy

Package reusing;

: Reusing/finaldata.java
The effect of final on fields.
Import java.util.*;
Import static net.mindview.util.print.*;

Class Value {
int i; Package access
Public Value (int i) {this.i = i;}
}



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];
Print (FD1);
Print ("Creating new FinalData");
FinalData fd2 = new FinalData ("Fd2");
Print (FD1);
Print (FD2);
}
}

/* Output:
Fd1:i4 = Int_5 = 18
Creating New FinalData
Fd1:i4 = Int_5 = 18
Fd2:i4 = Int_5 = 18
*/

Since both Valueone and Value_two are fianl basic types with compile-time values, they can both be used as compile time constants with no significant difference. Value_three is a more typical way of defining constants: it is defined as public, can be accessed by anyone, defined as static, only one is emphasized, and defined as FIANL, which indicates that it is a constant. Note that the final static base type with a constant initial value (that is, the compile-time constant) is all capitalized and is separated by an underscore between letters and letters.

We can't assume that some data is fianl to know its value at compile time. The use of random numbers at run time to initialize the values of I4 and int_5 is called a description of this. The case section also shows the distinction between defining FIANL data as static and non-static. This difference is only apparent when the values are initialized within the runtime, because the compiler treats the compile-time values equally (and they may disappear because of optimizations). This difference is seen when running. Note that the values I4 in this fd1 and FD2 are unique and are initialized to 15, 13 each time. The value of int_5 can not be changed by creating a second FinalData object. This is because he is static and is initialized when the class is loaded (that is, when the class object is first created), not every time it is created.




If it's difficult to see the above examples to understand the parts of my color, consider the following example:




[Java] View plaincopy

public class B3 {
Static random R =new Random (12);
Final int int1= r.nextint (100);//Generate 0-99 random number
static final int int_2= r.nextint (100);


public static void Main (string[] args) {
B3 b1=new B3 ();
System.out.println ("Int1:" +b1.int1+ "int_2:" +b1.int_2);
B3 b2=new B3 ();
b2.int_2=100;//Error Assignment
System.out.println ("Int1:" +b2.int1+ "int_2:" +b2.int_2);

}

}

Start Main () first executes the B3 b1=new B3 (), creates the first object of the B3, which initializes the static final int int_2= R.nextint (100), and then initializes the final int int1= R.nextint ( 100), so the result of the first output statement is Int1:12 int_2:66. Next, you create the second object of B3, which also causes the initialization of the members in the B3 class, but the static final int int_2= R.nextint (100), which is not initialized and why it was mentioned earlier. The result of the output is int1:56 int_2:66. The value of the output int_2 two times is the same.

In our first case, V1 to Val_3 to illustrate the meaning of final references. As seen in the main () method, you can change the value of an object array a, but you cannot point a reference to another object. It seems to make the base type fianl more useful than the reference type becomes final.

Java may generate "blank final", so-called blank final refers to a domain that is declared final without giving the initial value. The compiler will ensure that the final domain is initialized before use, regardless of the circumstances. But the blank final provides a lot of flexibility in the use of fianl, and for this reason, a fianl domain can be different depending on some object, while maintaining a constant feature. The following example illustrates a point.


[Java] View plaincopy

Class Poppet {
private int i;
Poppet (int ii) {i = II;}
}

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) {
New Blankfinal ();
New Blankfinal (47);
}
} //



Final parameter

In Java, the parameters in the parameter list may be declared as final in a declarative way. This means that you have no hair changing the object that the parameter points to.

[Java] View plaincopy

Class Gizmo {
public void Spin () {}
}

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 ();
}
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);
}
} //

The method F () G () shows that the parameters of the base type are specified as final is the result of the occurrence: You can read the parameters, but you cannot modify the parameters. This feature is used only to pass data to an anonymous inner class.

Final method

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

The second reason for the previous recommendation to use the final method is efficiency. In early implementations of Java, if a method is indicated as FIANL, it is agreed that the compiler will turn all calls to the method into inline calls. When the compiler discovers a final method invocation command, it will execute the method invocation mechanism (pressing the parameters into the stack, jumping to the method code, and then jumping back and cleaning the parameters in the stack, processing the return value), according to its own discretion, skipping the normal invocation of the Insert program code. and replace the method call with a copy of the actual code in the method body. This will eliminate the overhead of the method call. Of course, if a method is large, your program code expands, so you may not see the performance improvement that comes with embedding, because the performance is reduced by the amount of time spent in the method.

I don't know where the color is. I do not know the person who has seen the idea of Java programming and know to explain the explanation.

In the most up-to-date Java version, virtual machines (especially hotspot technology) can detect these situations and optimize additional inline calls that eliminate these efficiencies, and therefore no longer need to use the final method for optimization. In fact, this practice is gradually being discouraged. When using Java SE5/6, you should let the compiler and the JVM handle the efficiency issue, and only if you want to explicitly prohibit the overlay, set the method to Fianl.

Final and Private keywords

All private methods in a class are implicitly set to final. Because you cannot access the private method, you cannot overwrite it. You can add a final modifier to the private method, but this is meaningless.

[Java] View plaincopy

Class Withfinals {
Identical to "private" alone:
Private final void F () {print ("withfinals.f ()");}
Also automatically "final":
private void G () {print ("WITHFINALS.G ()");}
}

Class Overridingprivate extends Withfinals {
Private final void F () {
Print ("Overridingprivate.f ()");
}
private void G () {
Print ("overridingprivate.g ()");
}
}

Class OverridingPrivate2 extends Overridingprivate {
Public final void F () {
Print ("overridingprivate2.f ()");
}
public void G () {
Print ("OVERRIDINGPRIVATE2.G ()");
}
}

Overwrite occurs only if a method is part of a base class interface. That is, an object must be transformed upward into its base class and strip in the same way. If a method is private, it is not part of the base class interface. It is only a few program code hidden in the class, if there is a private method in a base class, a public,protected or package access method is created with the same name in the derived class, the method is simply the same name as the method in the base class. The base class method is not overridden. Because the private method is inaccessible and has good concealment, it is considered to exist because of the cause of the organization of his class, and nothing else is taken into account.

Final class

When you define a class as final, it indicates that you are not going to inherit the class, and that it is not possible for others to do so. In other words, for some reason, you never need to make any changes to the design of the class, or for security reasons, you don't want him to have subclasses.

[Java] View plaincopy

Class Smallbrain {}

Final class Dinosaur {
int i = 7;
int j = 1;
Smallbrain x = new Smallbrain ();
void F () {}
}

//! Class further extends dinosaur {}
Error:cannot extend final class ' dinosaur '

public class Jurassic {
public static void Main (string[] args) {
Dinosaur n = new Dinosaur ();
N.F ();
N.I = 40;
n.j++;
}
}

Note that the final class domain can be selected as or not final based on the individual's wishes. The same rules apply to fields that are defined as final, regardless of whether the class is defined as final. However, because final is not inheritable, the methods in the final-decorated class are implicitly set to FIANL, because you cannot overwrite them. You can add final to a method in the Fianl class, but that doesn't make any sense.

[Java] Final keyword

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.