Order of static variable initialization
1. Simple Rules
First look at a section of the most common Java code:
public class Test
{public
static Test1 t = new Test1 ();
public static int a = 0;
public static int B;
public static void Main (string[] arg)
{
System.out.println (TEST.A);
System.out.println (test.b);
}
Class Test1
{public
Test1 ()
{
test.a++;
test.b++
}
}
Let's guess what the console output is.
OK, you may have guessed the results below, so you are familiar with Java.
Copy Code code as follows:
If you don't understand why it outputs the results above, I'll tell you.
The initialization of Java static variables follows these rules:
- Static variables are declared and set to the default value of the type, in the order in which they are declared, but are not assigned to the initialized value.
- After the declaration is complete, set the initialized value in the order in which it was declared, and skip if the value is not initialized.
See this will understand that the original TEST.A value has changed three times.
Set to 0>>test1::test1 when declared as 1>>test.a initialized to 0
2. Complex rules
Understand this, please look at the following code again.
public class A {public static int b = B.A;
public static A plus =new a ("a");
public static final int finalint = (int) (Math.random () *100);
public static B p = new B ("A");
public static final String finalstr = "Finalstr";
public static final Integer Finalinteger = new Integer (10);
public static int a = 1;
public static B c = null;
Public A (String from) {System.out.println ("-----------begin a::a----------------");
System.out.println ("A::a, from=" +from);
System.out.println ("A::a, a.b=" +a.b);
System.out.println ("A::a, a.finalint=" +a.finalint);
System.out.println ("A::a, b.a=" +B.A);
System.out.println ("A::a, b.plus=" +b.plus);
System.out.println ("-----------End a::a----------------");
public static void Main (string[] arg) {System.out.println ("Main, a.b=" +a.b);
System.out.println ("Main, b.t=" +b.t);
System.out.println ("Main, c.a=" +C.A);
Class B {public static int t = A.A;
public static A plus = new A ("B");
public static int a = 1; PublicB (String from) {System.out.println ("-----------begin B::B----------------");
System.out.println ("B::b, from=" +from);
System.out.println ("B::b, b.a=" +B.A);
System.out.println ("B::b, a.a=" +a.a);
System.out.println ("B::b, a.p=" +A.P);
System.out.println ("B::b, a.plus=" +a.plus);
System.out.println ("B::b, a.finalint=" +a.finalint);
System.out.println ("B::b, a.finalinteger=" +a.finalinteger);
System.out.println ("B::b, a.finalstr=" +a.finalstr);
System.out.println ("-----------End b::b----------------");
Class C {public static final A = new A ("C");}
Can you guess the output? I was writing on one side of the test, so I didn't guess. haha
The console output results are:
-----------begin a::a----------------
a::a, from=b
a::a, a.b=0 a::a
, a.finalint=0 a::a
, b.a=0
A :: A, B.plus=null
-----------end a::a----------------
-----------begin a::a----------------
a::a, from= A
a::a, a.b=1
a::a, a.finalint=0
a::a, b.a=1 a::a
, b.plus=a@a90653
-----------End a::a----- -----------
-----------begin b::b----------------
b::b, From=a
b::b, b.a=1 b::b
, a.a=0
B: : B, A.p=null
b::b, a.plus=a@1fb8ee3
b::b, a.finalint=61 b::b, A.finalinteger=null b::b
, A.finalstr=finalstr
-----------End b::b----------------
Main, a.b=1
Main, b.t=0
----------- Begin A::A----------------
a::a, from=c
a::a, a.b=1 a::a, a.finalint=61 a::a, b.a=1 a::a
, b.plus=a@a90653
-----------End a::a----------------
Main, c.a=a@61de33
You didn't guess the result, haha.
A sentence to explain the results of the implementation of the program, or to a very long space. Here we write the rules for the initialization of Java static variables directly.
The rules of the first paragraph remain valid, but are not sound.
- Only the active request of a class, this class will be initialized, contains only static variables, functions, such as static things.
- When inheriting a relationship, the parent class is initialized and the subclass is initialized.
- Static variables are declared and set to the default value of the type, in the order in which they are declared, but are not assigned to the initialized value.
- After the declaration is complete, set the initialized value in the order in which it was declared, and skip if the value is not initialized.
- When A.B=B.A is initialized, the initialization a.b is paused, the current class is set to B, jumps to step 3, and executes.
- When initializing B.plus = new A, pause initialization b.plus, instantiate a and assign value to B.plus.
- When a B.A value is needed in the constructor of a, the B.A is initialized and in a paused initialization state, taking the current value of the B.A directly, and no longer waits for the B.A to initialize.
- Final, static constants actually follow the initialization of ordinary static variables, but at compile time, the compiler replaces immutable constant values where they are used. You can view it with a Java decompile tool.
Initialization of static data
a static-qualified field is called a class field, which means that the owner of the field is not an object but a class. No matter how many objects are created, there is only one copy of the static data.
The static field is always initialized in the class before the general field is initialized. The constructor is then initialized. However, if you do not create an object for this class, the object is not initialized and is executed only once.
As the following code, in the Staticinitialization class, initialize the static table = new Table () before initializing the Table object, otherwise it will not be initialized.
Class Bowl {
Bowl (int marker) {
print ("Bowl (+ marker +)");
}
void F1 (int marker) {
print ("F1 (" + marker +) ");
}
Class Table {
static Bowl bowl1 = new Bowl (1);
Table () {
print ("table ()");
BOWL2.F1 (1);
}
void F2 (int marker) {
print (F2 ("+ marker +"));
}
static Bowl bowl2 = new Bowl (2);
}
Class Cupboard {
Bowl bowl3 = new Bowl (3);
static Bowl Bowl4 = new Bowl (4);
Cupboard () {
print ("cupboard ()");
BOWL4.F1 (2);
}
void F3 (int marker) {
print (F3 ("+ Marker +"));
}
static Bowl bowl5 = new Bowl (5);
}
public class Staticinitialization {public
static void Main (string[] args) {
print (' Creating new Cupboard () in M Ain ");
New Cupboard ();
Print ("Creating new Cupboard () in main");
New Cupboard ();
TABLE.F2 (1);
CUPBOARD.F3 (1);
}
Static Table table = new table ();
Static cupboard cupboard = new cupboard ();
}
Output:
Bowl (1)
Bowl (2)
Table ()
F1 (1)
Bowl (4)
Bowl (5)
Bowl (3)
Cupboard () F1 (2) Creating new Cupboard () in main
Bowl (3)
cupboard ()
F1 (2)
creating new Cupboard () in main
Bowl (3)
Cupboard ()
F1 (2)
F2 (1)
F3 (1)
Static initialization of the display (i.e., static blocks)
wrapping multiple initialization statements in a static curly brace, called a stationary block, is actually a combination of multiple static writes, essentially the same. This is performed only the first time an object is created or a field is first accessed, and only once.
Class Cup {
cup (int marker) {
print ("Cup (+ marker +)");
}
void f (int marker) {
print ("f (" + marker +) ");
}
Class Cups {
static Cup cup1;
Static Cup cup2;
static {
Cup1 = new Cup (1);
cup2 = new Cup (2);
}
Cups () {
print ("Cups ()");
}
public class Explicitstatic {public
static void Main (string[] args) {
print ("Inside main ()");
CUPS.CUP1.F (99); (1)
}
//static Cups Cups1 = new Cups ();//(2)
//static Cups CUPS2 = new Cups ();//(2)
}
Output:
Inside Main ()
Cup (1)
Cup (2)
F (99)
Non-static instance initialization
This is nothing to say, is common initialization, in order to execute, can be executed multiple times.
Class Mug {
Mug (int marker) {
print ("Mug (+ marker +)");
}
void f (int marker) {
print ("f (" + marker +) ");
}
public class Mugs {
Mug mug1;
Mug Mug2;
{
mug1 = new Mug (1);
MUG2 = new Mug (2);
Print ("Mug1 & Mug2 Initialized");
}
Mugs () {
print ("Mugs ()");
}
Mugs (int i) {
print ("Mugs (int)");
}
public static void Main (string[] args) {
print ("Inside main ()");
New Mugs ();
Print ("New mugs () completed");
New Mugs (1);
Print ("New mugs (1) completed");
}
Inside Main ()
Mug (1)
Mug (2)
Mug1 & mug2 initialized mugs
()
new Mugs ()
completed Mug (1)
Mug (2)
Mug1 & mug2 initialized
mugs (int)
new Mugs (1) completed