java靜態代碼塊、靜態方法、靜態變量、構造代碼塊、普通代碼塊


一、靜態代碼塊

  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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM