Java static與final使用詳解

 static是靜態修飾關鍵字,可以修飾變量和程序塊以及類方法:

       當定義一個static變量的時候jvm會將將其分配在內存堆上,所有程序對它的引用都會指向這一個地址而不會重新分配內存;

       當修飾一個程序塊的時候(也就是直接將代碼寫在static{...}中)時候,虛擬機就會優先加載靜態塊中代碼,這主要用於系統初始化;

       當修飾一個類方法時候你就可以直接通過類來調用而不需要新建對象。

            1、static修飾屬性:無論一個類生成了多少個對象,所有這個對象共用唯一一份靜態的成員變量一個對象對該靜態成員變量進行了修改,其他對象的該靜態成員變量的值也會隨之發生變化。如果一個成員變量是static的,那麼我們可以通過類名.成員變量名的方式來使用它(推薦使用這種方式)。

             2、static修飾方法:static修飾的方法叫做靜態方法。對於靜態方法來說,可以使用類名.方法名的方式來訪問。
 

public class StaticTest {
    public static void main(String[] args) {
        MyStatic.output();
    }
}
class MyStatic{
    public static void output(){
        System.out.println("output");
    }
}

3、靜態方法只能繼承,不能重寫(Override)。

輸出結果:父類

4、final關鍵字:final可以修飾屬性、方法、類。

5、final修飾類:當一個類被final所修飾時,表示該類是一個終態類,即不能被繼承。

 6、final修飾方法:當一個方法被final所修飾的時,表示該方法是一個終態方法,即不能被重寫(Override)。

7、 final修飾屬性:當一個屬性被final所修飾時,表示該屬性不能被改寫。

8、當final修飾一個原生數據類型時,表示該原生數據類型的值不能發生變化(比如說不能從10變爲20);如果final修飾一個引用類型時,表示該引用類型不能再指向其他對象了,但該引用所指向的對象的內容是可以發生變化的。

原生數據類型案例:

圖中的錯誤是無法爲最終變量age分配值

引用類型案例:

 圖中錯誤是無法爲最終變量address分配值

 該引用所指向的對象的內容是可以發生變化的

9、對於final類型成員變量,一般來說有兩種賦值方式:

     a) 在聲明final類型的成員變量時就賦初值

     b) 在聲明final類型的成員變量時不賦初值,但在類的所有構造方法中都爲其賦上初值

public class FinalTest {
    final int a;
 
    public FinalTest() {
        a = 0;
    }
 
    public FinalTest(int a) {
        this.a = a;
    }
}

10、static靜態代碼塊。靜態代碼塊的作用也是完成一些初始化工作。首先執行靜態塊,然後執行構造方法。靜態代碼塊在類被加載的時候執行,而構造方法是在生成對象的時候執行;要調用某個類來生成對象,首先需要將類加載到Java虛擬機上(JVM),然後由JVM加載這個類來生成對象。

 11、類的靜態代碼塊只會執行一次,是在類被加載的時候執行的,因爲每個類只會加載一個,所以靜態代碼塊也只會被執行一次;而構造方法則不然,每次生成一個對象的時候都會調用類的構造方法,所以new一次就會調用構造方法一次。

 12、如果繼承體系既有構造方法,又有靜態代碼塊,那麼首先執行最頂層的類的靜態代碼塊,一直執行到最底層類的靜態代碼塊,然後再去執行最頂層類的構造方法,一直執行到最底層的構造方法,注意:靜態代碼塊只會執行一次。
 

public class StaticTest5 {
    public static void main(String[] args) {
        new R();
        new R();
    }
}
class P{
    //static靜態代碼塊
    static {
        System.out.println("static block");
    }
    public P(){
        System.out.println("P constructor");
    }
}
class Q extends P{
    static {
        System.out.println("static block");
    }
    public Q(){
        System.out.println("Q constructor");
    }
}
class R extends Q{
    static {
        System.out.println("static block");
    }
    public R(){
        System.out.println("R constructor");
    }
}

輸出結果:
 

static block 

static block 

static block 

P constructor 

Q constructor 

R constructor 

P constructor 

Q constructor 

R constructor

13、不能在靜態方法中訪問非靜態的成員變量:可以在靜態方法中訪問靜態的成員變量。可以在非靜態方法中訪問靜態的成員變量。

14、總結:靜態的只能訪問靜態的;非靜態的訪問一切。不能在靜態方法中使用this關鍵字。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章