1. 程式人生 > >Java——static關鍵字

Java——static關鍵字

前言



static關鍵字算是Java中比較複雜的關鍵字之一,它可以修飾變數、方法、類以及程式碼塊。下面將介紹static的具體使用。

  • static引入的目的
  • static的作用
  • java中的主方法入口:public static void main(String[] args)

  • 引入static的目的



    在《Java程式設計思想》中對static的描述有這樣的一句話:

    static方法就是沒有this的方法。在static的方法內部不能呼叫非靜態方法,反過來到是可以的。而且可以在沒有建立任何物件的前提下,僅僅通過類本身來呼叫static方法。


    這最後一句便是引入static主要的用途,免去建立類物件的開銷就可以呼叫類中的方法,可以說是十分誘人。



    static的作用



    static修飾變數

    private static int num;

    變數num可以稱為靜態變數也可以稱為類變數。

    static修飾屬性只能修飾類屬性,不可以修飾區域性變數,如方法中的定義的屬性。Java中規定如此。

    Java中的static和C++中的static含義是不一樣的,C++中的static修飾的變數是全域性變數,而Java中沒有全域性變數的概念,在Java中使用static修飾的類屬性是存放在方法區的,為該類所有物件共享的變數,與具體某個物件沒有關係


    static屬性和非static屬性的區別主要有兩點:①在記憶體區域的儲存位置不同,static屬性存放在方法區,非static屬性存放在堆疊區。②static屬性是屬於類物件的公共屬性,可以在沒有例項化物件的前提下使用類名.靜態屬性名的方式訪問;而非static屬性則需要使用物件進行訪問。

    關於什麼時候該使用static屬性?

    需要進行描述共享資訊的屬性並且該屬性不需要重複開闢記憶體空間而且便於修改,則使用static進行修飾該變數。其餘情況,不建議使用static修飾變數。



    static修飾方法


    public static void printNumberOfStudent(){
      ...
    }

    被static修飾的方法叫做靜態方法。靜態方法同靜態變數一樣可以直接使用類名稱.靜態方法名呼叫。若是使用類名呼叫靜態方法需要滿足該方法不是private。在非靜態方法中是可以使用this訪問靜態變數。

    在使用靜態方法時需要注意兩點:

    • 靜態方法中是不存在this的。因為this是指向當前物件的,靜態方法是與類相關的,與物件無關,不存在物件呼叫問題。一般直接使用類名.靜態方法名 進行訪問

    • 靜態方法內部只能直接呼叫靜態方法和靜態成員。呼叫普通方法會報錯,在普通方法中可以呼叫靜態方法。
      因為普通方法一般會將物件作為隱藏實參傳入並用this指向,在沒有建立物件時,普通方法中就不存在this,呼叫包含普通方法的靜態方法就會報錯!



    static修飾程式碼塊



    在程式編寫中可以直接使用 {...}定義一段語句塊,這個語句塊就是程式碼塊,使用static修飾的語句塊就叫做靜態程式碼塊。

    觀察下面程式的結果,分析靜態塊在程式中的執行順序:

    public class A {
        A(){
            System.out.println("A constructor");
        }
        static {
            System.out.println("A's static block");
        }
    }
    
    public class B extends A{
        B(){
            System.out.println("B constructor");
        }
        static {
            System.out.println("B's static block");
        }
    }
    
    public class StaticBlock {
        public static void main(String[] args) {
            B objb = new B();
        }
    }
    
    /*output
    A's static block
    B's static block
    A constructor
    B constructor
    */

    可以看出靜態程式碼塊的執行順序優先於建構函式,在程式執行時,會先找到main入口,然後準備載入類B,發現B有父類A,於是先去載入A,靜態程式碼塊就是在類載入的時候執行的。在靜態塊執行完後,就會去執行建構函式。

    靜態塊因為在建構函式之前執行,所以常用來初始化靜態變數

    public  class Student {
        private static int numOfStu;
        private String name;
        private int age;
    
        static {
            numOfStu = 0;
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
            numOfStu++;
        }

    靜態程式碼塊可以在類的任意位置定義(方法中不可以),不會影響其優先於建構函式執行的順序。但是多個靜態塊的執行順序會依據其宣告的前後執行。

    public  class Student {
        private static int numOfStu;
        private String name;
        private int age;
    
        static {
            numOfStu = 0;
            System.out.println("first sttaic block");
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
            numOfStu++;
        }
    
        static {
            System.out.println("second sttaic block");
        }
    
        public static void main(String[] args) {
            Student stu1 = new Student("sakura",20);
        }
    }
    /*
    output:
    first sttaic block
    second sttaic block
    */



    static修飾內部類



    內部類顧名思義就是定義在一個類中的類。使用static定義的屬性或者方法是不受類例項化物件的控制的,所以,如果內部類被static修飾,是不會受到外部類例項化物件控制。此時, 內部類就相等於變成了一個外部類,並且只能訪問外部類中的static屬性或者方法。關於內部類,後面會詳細介紹。



    java中的主方法入口:public static void main(String[] args)


    class Test{
      ...
      public static void main(String[] args){
      ...
      }
    }

    現在來看待被static修飾的主函式,這樣的好處可能就是:不用建立當前類的物件就可以呼叫,節省空間。

    【public】: 主方法是程式的開始,所以這個方法對任何操作都應該是可見

    【static】: 此方法由類名稱呼叫,在命令列使用java Test是呼叫Test.main主方法

    【void】: 主方法是一切執行的開始點,既然是起點,那麼就沒有回到其他方法中的返回值

    【String[] args】: 傳遞給程式的引數。輸入的引數以空格隔開,若是輸入的引數本省有空格,則使用雙引號將該引數括起來



    小結



    介紹了Java中static關鍵字的基礎應用:修飾變數、方法等。Java中還可以利用static關鍵字實現 單例模式,這些後面介紹。

    參考:《Java程式設計思想》