目錄
- 1、靜態代碼塊
- ①、格式
- ②、執行時機
- ③、靜態代碼塊的作用
- ④、靜態代碼塊不能存在任何方法體中
- ⑤、靜態代碼塊不能訪問普通變量
- 2、構造代碼塊
- ①、格式
- ②、執行時機
- ③、構造代碼塊的作用
- 3、構造函數
- 4、普通代碼塊
- 5、執行順序
- 6、父類和子類執行順序
1、靜態代碼塊
①、格式
在java類中(方法中不能存在靜態代碼塊)使用static關鍵字和{}聲明的代碼塊:
public class CodeBlock { static{ System.out.println("靜態代碼塊"); } }
②、執行時機
靜態代碼塊在類被加載的時候就運行了,而且只運行一次,并且優先于各種代碼塊以及構造函數。如果一個類中有多個靜態代碼塊,會按照書寫順序依次執行。后面在比較的時候會通過具體實例來證明。
③、靜態代碼塊的作用
一般情況下,如果有些代碼需要在項目啟動的時候就執行,這時候就需要靜態代碼塊。比如一個項目啟動需要加載的很多配置文件等資源,我們就可以都放入靜態代碼塊中。
④、靜態代碼塊不能存在任何方法體中
這個應該很好理解,首先我們要明確靜態代碼塊是在類加載的時候就要運行了。我們分情況討論:
對于普通方法,由于普通方法是通過加載類,然后new出實例化對象,通過對象才能運行這個方法,而靜態代碼塊只需要加載類之后就能運行了。
對于靜態方法,在類加載的時候,靜態方法也已經加載了,但是我們必須要通過類名或者對象名才能訪問,也就是說相比于靜態代碼塊,靜態代碼塊是主動運行的,而靜態方法是被動運行的。
不管是哪種方法,我們需要明確靜態代碼塊的存在在類加載的時候就自動運行了,而放在不管是普通方法還是靜態方法中,都是不能自動運行的。
⑤、靜態代碼塊不能訪問普通變量
這個理解思維同上,普通變量只能通過對象來調用,是不能放在靜態代碼塊中的。
2、構造代碼塊
①、格式
在java類中使用{}聲明的代碼塊(和靜態代碼塊的區別是少了static關鍵字):
public class CodeBlock { static{ System.out.println("靜態代碼塊"); } { System.out.println("構造代碼塊"); } }
②、執行時機
構造代碼塊在創建對象時被調用,每次創建對象都會調用一次,但是優先于構造函數執行。需要注意的是,聽名字我們就知道,構造代碼塊不是優先于構造函數執行,而是依托于構造函數,也就是說,如果你不實例化對象,構造代碼塊是不會執行的。怎么理解呢?我們看看下面這段代碼:
public class CodeBlock { { System.out.println("構造代碼塊"); } public CodeBlock(){ System.out.println("無參構造函數"); } public CodeBlock(String str){ System.out.println("有參構造函數"); } }
我們反編譯生成的class文件:
5、執行順序
靜態代碼塊>構造代碼塊>構造函數>普通代碼塊
public class CodeBlock { static{ System.out.println("靜態代碼塊"); } { System.out.println("構造代碼塊"); } public CodeBlock(){ 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();; } }
反編譯生成的class文件: