一、靜態代碼塊
1.在java類中(方法中不能存在靜態代碼塊)使用static關鍵字和{}聲明的代碼塊:
public class CodeBlock{ static{ System.out.println("靜態代碼塊"); } }
2.執行時機
靜態代碼塊在類被加載的時候就運行了,而且只運行一次,並且優先於各種代碼塊以及構造函數。如果一個類中有多個靜態代碼塊,就會按照書寫的順序執行。
3.靜態代碼塊的作用:
一般情況下,如果有些代碼需要在項目啟動的時候執行,這時就需要靜態代碼快,比如一個項目啟動需要加載很多配置文件等資源,就可以都放在靜態代碼塊中。
4.靜態代碼塊不能存在於任何方法體中
這個很好理解,首先要明確靜態代碼塊是在類加載的時候就運行了,我們分情況進行討論:
(1)對於普通方法,由於普通方法是通過加載類,然后new出實例化對象,通過對象才能運行這個方法,而靜態代碼塊只需要加載類之后就能運行了。
(2)對於靜態方法,在類加載的時候,靜態方法就已經加載了,但是我們必須通過類名或者對象名才能進行訪問,也就是說相對於靜態代碼塊,靜態代碼塊是主動運行的,而靜態方法是被動運行的。
(3)不管哪種方法,我們需要明確的是靜態代碼塊的存在在類加載的時候就自動運行了,而放在不管是普通方法中還是靜態方法中,都是不能自動運行的。
5.靜態代碼塊不能訪問普通代變量
(1)這個理解思維同上,普通代碼塊只能通過對象來進行調用,而不能防砸靜態代碼塊中。
二、構造代碼塊
1.格式:java類中使用{}聲明的代碼塊(和靜態代碼塊的區別是少了static關鍵字)
1 public class codeBlock { 2 static { 3 System.out.println("靜態代碼塊"); 4 } 5 { 6 System.out.println("構造代碼塊"); 7 } 8 }
2.執行時機
構造代碼塊在創建對象的時候被調用,每創建一次對象都會調用一次,但是優先於構造函數執行,需要注意的是,聽名字我們就知道,構造代碼塊不是優先於構造函數執行的,而是依托於構造函數,也就是說,如果你不實例化對象,構造代碼塊是不會執行的。怎么理解呢?先看看下面的代碼段:
public class codeBlock { static { System.out.println("靜態代碼塊"); } { System.out.println("構造代碼塊"); } public codeBlock(){ System.out.println("無參構造函數"); } public codeBlock(String str){ System.out.println("有參構造函數"); } }
我們反編譯生成的.class文件
3.構造代碼塊的作用:
(1)和構造函數的作用類似,都能夠對象記性初始化,並且只要創建一個對象,構造代碼塊都會執行一次。但是反過來,構造函數則不會再每個對象創建的時候都執行(多個構造函數的情況下,建立對象時傳入的參數不同則初始化使用對應的構造函數)
(2)利用每次創建對象的時候都會提前調用一次構造代碼塊特性,我們做諸如統計創建對象的次數等功能。
三、構造函數
1.構造函數必須和類名完全相同。在java中,普通函數可以和構造函數同名,但是必須帶有返回值。
2.構造函數的功能主要用於在類創建時定義初始化的狀態。沒有返回值,也不能用void來進行修飾。這就保證額它不僅什么也不用自動返回,而且根本不能有任何選擇,而其他方法都有返回值,盡管方法體本身不會自動返回什么,但是仍然可以返回一些東西,而這些東西可能是不安全的;
3.構造函數不能被直接調用,必須通過New運算符在創建對象的時才會自動調用;而一般的方法是在程序執行到它的時候被調用的
4.當定義一個類的時候,通常情況下都會現實該類的構造函數,並在函數中指定初始化的工作也可省略,不過Java編譯期會提供一個默認的構造函數,此默認的構造函數是不帶參數的,即空參構造。而一般的方法不存在這一特點。
四、普通代碼塊
1.普通代碼塊和構造代碼塊的區別是,構造代碼塊是在類中定義的,而普通代碼塊是在方法體重定義的。並且普通代碼塊的執行順序和書寫順序是一致的
public class sayHelllo { { System.out.println("普通代碼塊"); } }
五、執行順序
1.靜態代碼塊>構造代碼塊>構造函數>普通代碼塊
public class codeBlock { static { System.out.println("靜態代碼塊"); } { System.out.println("構造代碼塊"); } public codeBlock(){ System.out.println("無參構造函數"); } public codeBlock(String str){ System.out.println("有參構造函數"); } public void sayHello(){ System.out.println("普通代碼塊"); } public static void main(String[] args) { System.out.println("執行了main方法"); new codeBlock().sayHello(); System.out.println("---------------------------"); new codeBlock().sayHello(); } }
六、實例
public class Test1 { static{ int x = 5 ; } static int x ,y; public static void main(String args[]){ x--; myMethod();//運行myMethod方法,x之前是-1,開始調用myMethod()函數 System.out.println(x+y++ +x); } public static void myMethod(){ y=x++ + ++x; //步驟2:這個地方的調用要注意:x++ + ++x 是將-1先自加然后加1,得到y=0
System.out.println(y);
System.out.println(x);步驟3:此時x=1 } }
//最終的運行結果為2
執行過程分析:
1.static { int x =5;} //靜態代碼塊,在類加載的時候回被加載並且執行,但是由於是局部變量,所以x= 5 不影響后面的值
2.static int x,y; 這個時候會將x和y進行初始化,得到x=0;y=0