Detailed explanation of static block and static variable loading order in JAVA

Source blog: https://www.cnblogs.com/leiqiannian/p/7922824.html

public class test {                         //1.第一步,准备加载类
<span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">static</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">main</span>(<span class="hljs-params">String[] args</span>) </span>{
    <span class="hljs-keyword"><span class="hljs-keyword">new</span> test();                         <span class="hljs-comment"><span class="hljs-comment">//4.第四步,new一个类,但在new之前要处理匿名代码块        </span>
}

<span class="hljs-keyword"><span class="hljs-keyword">static</span> <span class="hljs-keyword"><span class="hljs-keyword">int</span> num = <span class="hljs-number"><span class="hljs-number">4</span>;                    <span class="hljs-comment"><span class="hljs-comment">//2.第二步,静态变量和静态代码块的加载顺序由编写先后决定 </span>

{
    num += <span class="hljs-number"><span class="hljs-number">3</span>;
    System.<span class="hljs-keyword"><span class="hljs-keyword">out</span>.println(<span class="hljs-string"><span class="hljs-string">"b"</span>);           <span class="hljs-comment"><span class="hljs-comment">//5.第五步,按照顺序加载匿名代码块,代码块中有打印</span>
}

<span class="hljs-keyword"><span class="hljs-keyword">int</span> a = <span class="hljs-number"><span class="hljs-number">5</span>;                             <span class="hljs-comment"><span class="hljs-comment">//6.第六步,按照顺序加载变量</span>

{ <span class="hljs-comment"><span class="hljs-comment">// 成员变量第三个</span>
    System.<span class="hljs-keyword"><span class="hljs-keyword">out</span>.println(<span class="hljs-string"><span class="hljs-string">"c"</span>);           <span class="hljs-comment"><span class="hljs-comment">//7.第七步,按照顺序打印c</span>
}

test() { <span class="hljs-comment"><span class="hljs-comment">// 类的构造函数,第四个加载</span>
    System.<span class="hljs-keyword"><span class="hljs-keyword">out</span>.println(<span class="hljs-string"><span class="hljs-string">"d"</span>);           <span class="hljs-comment"><span class="hljs-comment">//8.第八步,最后加载构造函数,完成对象的建立</span>
}

<span class="hljs-keyword"><span class="hljs-keyword">static</span> {                              <span class="hljs-comment"><span class="hljs-comment">// 3.第三步,静态块,然后执行静态代码块,因为有输出,故打印a</span>
    System.<span class="hljs-keyword"><span class="hljs-keyword">out</span>.println(<span class="hljs-string"><span class="hljs-string">"a"</span>);
}

<span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">static</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">run</span>(<span class="hljs-params"></span>)                    </span><span class="hljs-comment"><span class="hljs-function"><span class="hljs-comment">// 静态方法,调用的时候才加载// 注意看,e没有加载</span>
</span>{
    System.<span class="hljs-keyword"><span class="hljs-keyword">out</span>.println(<span class="hljs-string"><span class="hljs-string">"e"</span>);
}

}

General order: static block (static variable) -> member variable -> construction method -> static method 
1. Static code block (load only once) 2. Construction method (load once when an instance is created) 3. Static method Need to be called to execute, so the final result does not have e 
Write picture description here

Write picture description here

 public class Print {
 <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">Print</span>(<span class="hljs-params">String s</span>)</span>{
     System.<span class="hljs-keyword"><span class="hljs-keyword">out</span>.print(s + <span class="hljs-string"><span class="hljs-string">" "</span>);
 }

}

 public class Parent{

     public static Print obj1 = new Print("1"); public Print obj2 = new Print("2"); public static Print obj3 = new Print("3"); static{ new Print("4"); } public static Print obj4 = new Print("5"); public Print obj5 = new Print("6"); public Parent(){ new Print("7"); } }
 public class Child extends Parent{ static{ new Print("a"); } public static Print obj1 = new Print("b"); public Print obj2 = new Print("c"); public Child (){ new Print("d"); } public static Print obj3 = new Print("e"); public Print obj4 = new Print("f"); public static void main(String [] args){ Parent obj1 = new Child (); Parent obj2 = new Child (); } }

 

执行main方法,程序输出顺序为: 1 3 4 5 a b e 2 6 7 c f d 2 6 7 c f d 

The output result shows that the execution order of the program is: 
If the class has not been loaded: 
1. The static code block and static variable initialization of the parent class are executed first, and the execution order of the static code block and static variable is only related to the order in which the code appears .  
2. Execute the static code block and static variable initialization of the subclass.  
3. Execute the instance variable initialization of the  
parent class 4. Execute the constructor of the parent class  
5. Execute the instance variable initialization of the  
child class. 6. Execute the constructor of the child class. 

If the class has been loaded: 
the static code block and static variables do not need to be repeated When executing and then creating a class object, only the variable initialization and construction methods related to the instance are executed.

Guess you like

Origin blog.csdn.net/qq_41936224/article/details/108822166