The role of the static keyword.
The final keyword is one of the two questions that I have to ask during each interview. The other is the static one that the text will write. Like static, final is a small problem. We can see whether a person's foundation is solid and whether he or she has the research spirit at ordinary times.
Static variables and static methods
The most basic usage of static keywords is:
1. Variables modified by static belong to class variables, which can be directly referenced by class name. variable name without the need to create a new class.
2. The method modified by static is a class method, which can be directly referenced by class name. method name without the need to create a new class.
Static modified variables and static methods belong to static resources of the class. They are shared among class instances. In other words, they are changed in one place and changed everywhere. JDK places different static resources in different classes instead of all static resources in one class. Many people may take it for granted that, of course, this should be done, but have you ever wondered why? I personally think there are three main advantages:
1. Different classes have their own static resources, which can be used to classify static resources. For example, static resources related to mathematics are stored in java. lang. Math, and static resources related to Calendar are stored in java. util. Calendar.
2. Avoid duplicate names. It is also normal for different classes to have duplicate static variable names and static method names. If all the names are put together, the inevitable problem is that the names are repeated. What should we do at this time? Just put the classification.
3. It is easy to understand to avoid infinite expansion of static resources.
Okay, let's go a little deeper. This is also a confusing question for some people: Can static methods reference non-static resources? Can static resources be referenced in static methods? Can static resources be referenced in non-static methods? For example, if this code is used as an example, is there any error?
1 public class A2 {3 private int i = 1;4 5 public static void main(String[] args)6 {7 i = 1;8 }9 }
Of course there is a mistake, in the place of the first line. Consider this question as follows:
Static resources belong to the class, but they exist independently of the class. From the perspective of the JVM class loading mechanism, static resources are loaded during class initialization, rather than when the class is new. Class initialization is earlier than Class new, such as Class. the forName ("xxx") method initializes a class, but it does not have a new one. It just loads static resources of the class. Therefore, for static resources, it is impossible to know which non-static resources exist in a class; but for non-static resources, it is different because it is generated after the new, therefore, you can understand these things that belong to the class. The answer to the above questions is clear:
1. Can static methods reference non-static resources? No, something that is generated only when new is created. It is not known for static resources that exist after initialization.
2. Can static resources be referenced in static methods? Yes, because they are loaded during class initialization, and everyone knows each other.
3. Can static resources be referenced in non-static methods? Yes. The non-static method is the instance method, which is generated after the new method. It is known as the class content.
Static Block
Static blocks are also an important application of static. It is also used to initialize a class. Like static variables and static methods, the code in the static block is only executed once and only executed during class initialization. Static blocks are simple, but three small details are provided:
1 public class A 2 { 3 private static int a = B(); 4 5 static 6 { 7 System.out.println("Enter A.static block"); 8 } 9 10 public static void main(String[] args)11 {12 new A();13 }14 15 public static int B()16 {17 System.out.println("Enter A.B()");18 return 1;19 }20 }
The printed result is
Enter A.B()Enter A.static block
The first conclusion is that the loading order of static resources is strictly in the defined order of static resources. This is the same as Zhou Zhiming's statement in class initialization in "a deep understanding of Java Virtual Machine: Advanced JVM features and best practices".The <clinit> () method is generated by the compiler automatically collecting the values of all class variables in the class and combining the statements in the static statement block (static, the sequence collected by the compiler is determined by the order in which the statements appear in the source file."Is consistent.
Let's look at another example:
1 public class A 2 { 3 static 4 { 5 c = 3; 6 System.out.println(c); 7 } 8 9 private static int c;10 }
The error "Cannot reference a field before it is defined" is returned in line 6th of this Code ". The second conclusion is drawn from this example: the static code block can be assigned a value for the static variables defined after it, but cannot be accessed.
The last small example:
1 public class A 2 { 3 static 4 { 5 System.out.println("A.static block"); 6 } 7 8 public A() 9 {10 System.out.println("A.constructor()");11 }12 }
1 public class B extends A 2 { 3 static 4 { 5 System.out.println("B.static block"); 6 } 7 8 public B() 9 {10 System.out.println("B.constructor()");11 }12 13 public static void main(String[] args)14 {15 new B();16 new B();17 }18 }
The result is
A.static blockB.static blockA.constructor()B.constructor()A.constructor()B.constructor()
This example draws the third conclusion: the static code block is loaded strictly according to the sequence of the static code block of the parent class-> the static code block of the subclass, and is loaded only once.
Static modifier class
This is used less than the previous one. static is generally not allowed to modify the class. If static is used to modify a class, this class is a static internal class (note that only one internal class can be modified by static), that is, an anonymous internal class. Like the four denial mechanisms in the ThreadPoolExecutor of the thread pool CallerRunsPolicy, AbortPolicy, DiscardPolicy, and DiscardOldestPolicy are static internal classes. Static internal class-related content will be specifically mentioned when writing internal classes.
Import static
This is relatively unpopular, And it is rarely seen to be used in some places. It may be used when JUnit is used, and it is easier to write assert. Import static is a new feature after JDK1.5. These two keywords can be used to specify the static resources to be imported to a class without the class name. Resource name. You can directly use the resource name. Note that import static must be written in this way, but cannot be written as static import. For example:
1 import static java.lang.Math.*;2 3 public class A4 {5 public static void main(String[] args)6 {7 System.out.println(sin(2.2));8 }9 }
This write means that I have imported all the static resources under Math. In the main function, I can directly use sin (2.2) instead of Math. sin (2.2. Note that you need to write import static java. lang. math. *. * "is indispensable. With these two characters, all static resources under Math are imported and written as import static java. lang. math is faulty. Of course, we can also specify to only import a static resource. For example, we can only import the sin method under Math without importing all static resources under Math:
1 import static java.lang.Math.sin;2 3 public class A4 {5 public static void main(String[] args)6 {7 System.out.println(sin(2.2));8 }9 }
There is no problem with this writing. The same is true for importing static variables. If you are interested, try it yourself. For import static, my personal attitude is:
1. Some operations are simplified, such as static import of all static resources under Math, which can be much less "Math ."
2. Reduced code readability
We recommend that you import specific static resources in some scenarios. We do not recommend you use the ". *" import method.