天天看點

《Java迷之知識點》之-----static關鍵字

1.static是什麼

    static在java中的意思是“靜态的”,什麼是靜态的?靜态的 意味着這個東西和對象無關,和類有關。

2.static作用在變量上

    當static作用在變量上的時候,意味着這個變量被這個該類所有的對象共享(同一個hashCode位址),static表示的同一個hashCode,但不是表示該hash位址不可以改變,如果要該hash位址不改變,那是final的作用。看看如下代碼:

public class StaticTest {

    private static String staticVar = "aaa";

    public void changeStaticVar(){
        staticVar = "bbb";
        System.out.println(staticVar.hashCode());
    }

    public static void main(String[] args) {

        System.out.println(StaticTest.staticVar.hashCode());

        System.out.println("==============");

        StaticTest test = new StaticTest();
        test.changeStaticVar();
        System.out.println(StaticTest.staticVar.hashCode());

    }
}
//輸出結果
96321
==============
97314
97314
           

    由此可以證明,當static修飾變量的時候,它更像是“屬于”類的,而不是屬于某一個對象的。

3.static作用于方法上

    static作用于方法上,和作用于變量上的意義是大同小異的,它更像是“屬于”類的,而不是屬于某一個對象的。static方法在類執行個體化對象之前就已經存在。是以,在static方法中是不允許使用非static成員變量或方法的。為什麼?因為此時都沒有對象,怎麼使用對象的方法和變量?看看如下代碼:

public class StaticTest {

    private String var = "aaa";

    public static void changeStaticVar(){
        //var = "bbb"; 編譯器報錯
    }
    
}
           

    思考:main方法也是用static修飾的,它有什麼特别之處?其實它的特别之處就是用了static,我以前在學習java的時候,總是想不new對象,直接在main方法裡使用該類的其它方法,卻永遠都是報錯,原來就是這個static在作怪。由此更可以看出,在main方法開始的時候,其實沒有任何對象被執行個體出來,是以就沒有辦法使用非static方法,除非執行個體化出對象。

    那麼在反過來呢?在非static方法中能不能使用static變量?當然可以,非static的方法就是給對象調用的吧?對象已經生成了,static變量早已經生成了。

    另外,其實類的構造器都是static的。

4.static靜态塊

    static靜态塊在實際開發中非常有用,它在類加載的時候總是第一個被加載(僅次于靜态成員變量),看如下代碼

public class StaticTest {

    private String var = getVar();

    private static String staticVar = getStaticVar();

    static{
        System.out.println("static靜态塊");
    }

    public StaticTest() {
        System.out.println("構造方法");
    }

    public String getVar(){
        System.out.println("成員變量var");
        return "var";
    }

    public static String getStaticVar(){
        System.out.println("靜态成員變量staticVar");
        return "staticVar";
    }

    public static void main(String[] args) {
        StaticTest test = new StaticTest();
    }
    
}

//輸出結果
靜态成員變量staticVar
static靜态塊
成員變量var
構造方法
           

    其實從輸出結果就可以看出 static的特别:就是其獨立于對象之外。在對象還沒有生成的時候,它們就已經被執行個體化了。

    思考:如果StaticTest類繼承了一個和它差不多類,那麼執行個體化對象時,是父類的靜态成員變量先執行個體化?還是子類先?大家可以自行實驗。

5.static作用于類

    static不能作用于一般的類上,隻能作為某一個類的匿名類存在,雖然不知道有什麼意義:

public class StaticTest {

    static class InnerClass{

    }

    public static void main(String[] args) {
        InnerClass innerClass = new InnerClass();
    }

}
           

6.一個小例子

思考下面這段代碼的輸出順序是什麼

//父類
public class FatherClass {

    private String fs = finit();
    private static String fs1 = fstaticInit();

    private static String fstaticInit() {
        System.out.println("父類靜态成員變量初始化!");
        return "";
    }

    static {
        System.out.println("父類靜态塊初始化!");
    }

    public FatherClass(){
        System.out.println("父類構造函數初始化!");
    }

    private String finit(){
        System.out.println("父類成員變量初始化!");
        return "";
    }
}


//子類
public class InitClass extends FatherClass{

    private String s = init();
    private static String s1 = staticInit();

    private static String staticInit() {
        System.out.println("子類靜态成員變量初始化!");
        return "";
    }

    static {
        System.out.println("子類靜态塊初始化!");
    }

    public InitClass(){
        System.out.println("子類構造函數初始化!");
    }

    private String init(){
        System.out.println("子類成員變量初始化!");
        return "";
    }
    
}

//main
public class Main {

    public static void main(String[] args) {
        InitClass initClass = new InitClass();
    }
}

           

是不是非常好玩,自己體會,結果如下

1.父類靜态 成員變量初始化!
2.父類靜态塊初始化!
3.子類靜态成員變量初始化!
4.子類靜态塊初始化!
5.父類成員變量初始化!
6.父類構造函數初始化!
7.子類成員變量初始化!
8.子類構造函數初始化!

//序号是自己添加的
           

轉載于:https://my.oschina.net/u/3582320/blog/1503970