Java中非靜態成員變量、靜態成員變量的初始化時機


轉:

Java中非靜態成員變量、靜態成員變量的初始化時機。

版權聲明:技術就要分享才有意思,歡迎大家分享(注明出處),歡迎大家糾錯。 https://blog.csdn.net/SilenceCarrot/article/details/80403635

Java中非靜態成員變量、靜態成員變量的初始化時機。

非靜態變量

我們在這里分析三種結構,着重分析這三種結構的初始化順序:

  1. 成員變量初始化語句;
  2. 成員變量初始化塊;
  3. 構造函數;

示例一:

 

public class MyTest {

    private String name = "wei.hu";

    public MyTest(String name) {
        System.out.println("This is constructor. Will assign the variable name to: " + name + ".");

        System.out.println("Before the name was modified: " + this.name);
        this.name = name;
        System.out.println("After the name was modified: " + this.name);
    }

    {
        System.out.println("This is initialize block. Will assign the variable name to: chouchou");

        System.out.println("Before the name was modified: " + this.name);
        this.name = "chouchou";
        System.out.println("After the name was modified: " + this.name);
    }

    public String getName() {
        return name;
    }

    public static void main(String[] args) {
        MyTest myTest = new MyTest("mengna");
        System.out.println(myTest.getName());
    }
}


#輸出
This is initialize block. Will assign the variable name to: chouchou
Before the name was modified: wei.hu
After the name was modified: chouchou
This is constructor. Will assign the variable name to: mengna.
Before the name was modified: chouchou
After the name was modified: mengna
mengna

 


示例二:

public class MyTest {

    public MyTest(String name) {
        System.out.println("This is constructor. Will assign the variable name to: " + name + ".");

        System.out.println("Before the name was modified: " + this.name);
        this.name = name;
        System.out.println("After the name was modified: " + this.name);
    }

    private String name = "wei.hu";

    {
        System.out.println("This is initialize block. Will assign the variable name to: chouchou");

        System.out.println("Before the name was modified: " + this.name);
        this.name = "chouchou";
        System.out.println("After the name was modified: " + this.name);
    }

    public String getName() {
        return name;
    }

    public static void main(String[] args) {
        MyTest myTest = new MyTest("mengna");
        System.out.println(myTest.getName());
    }
}

#結果(與示例一相同)
This is initialize block. Will assign the variable name to: chouchou
Before the name was modified: wei.hu
After the name was modified: chouchou
This is constructor. Will assign the variable name to: mengna.
Before the name was modified: chouchou
After the name was modified: mengna
mengna

 

 

示例三:

public class MyTest {

    public MyTest(String name) {
        System.out.println("This is constructor. Will assign the variable name to: " + name + ".");

        System.out.println("Before the name was modified: " + this.name);
        this.name = name;
        System.out.println("After the name was modified: " + this.name);
    }

    {
        System.out.println("This is initialize block. Will assign the variable name to: chouchou");

        System.out.println("Before the name was modified: " + this.name);
        this.name = "chouchou";
        System.out.println("After the name was modified: " + this.name);
    }

    private String name = "wei.hu";

    public String getName() {
        return name;
    }

    public static void main(String[] args) {
        MyTest myTest = new MyTest("mengna");
        System.out.println(myTest.getName());
    }
}


#結果
This is initialize block. Will assign the variable name to: chouchou
Before the name was modified: null
After the name was modified: chouchou
This is constructor. Will assign the variable name to: mengna.
Before the name was modified: wei.hu
After the name was modified: mengna
mengna

分析:
注意本示例的結果與上面兩個示例的結果不同。
1、當我們想將成員變量name賦值為chouchou之前,發現this.name為null。也就是說初始化語句沒有先執行,而是先執行了初始化塊;
2、當在執行構造函數時,我們想將成員變量name賦值為mengna,發現賦值之前,this.name不再是chouchou,而是wei.hu,這說明了什么?
    因為初始化塊先執行,如果緊接着執行構造函數的話,那么在構造函數賦值語句執行之前,this.name應該是chouchou才對。但是在構造函數賦值語句執行之前,this.name的值變成了wei.hu,那么足以證明:
    1)初始化塊先執行;
    2)下來執行了初始化語句;
    3)最后執行了構造函數;

結論:
通過上面三個示例,我們可以發現,對於非靜態的成員變量:

  1. 初始化語句、初始化塊,總是先於構造函數執行;
  2. 初始化語句、初始化塊的和執行順序,取決於 初始化語句、初始化塊在代碼中的書寫順序。寫在上面的先執行。

靜態變量

我們在這里也分析三種結構:

  1. 靜態初始化語句;
  2. 靜態初始化塊;
  3. 構造函數;

示例一:

public class MyTest {

    public static String name = "wei.hu";

    public MyTest() {
        System.out.println("This is constructor. Will assign the variable name to: chouchou");

        System.out.println("Before the name was modified: " + name);
        name = "chouchou";
        System.out.println("After the name was modified: " + name);
    }

    static {
        System.out.println("This is static initialize block. Will assign the variable name to: mengna");

        System.out.println("Before the name was modified: " + name);
        name = "mengna";
        System.out.println("After the name was modified: " + name);
    }

    public static void main(String[] args) {
        System.out.println(MyTest.name);
    }
}


#結果
This is static initialize block. Will assign the variable name to: mengna
Before the name was modified: wei.hu
After the name was modified: mengna
mengna

分析:
通過打印輸出,我們發現在執行靜態初始快之前,靜態變量name已經初始化為wei.hu了。也就是說:
1、靜態初始化語句先執行;
2、下來執行靜態初始化塊;
3、構造函數未執行;
--------------------- 

示例二:

public class MyTest {

    public MyTest() {
        System.out.println("This is constructor. Will assign the variable name to: chouchou");

        System.out.println("Before the name was modified: " + MyTest.name);
        name = "chouchou";
        System.out.println("After the name was modified: " + MyTest.name);
    }

    static {
        System.out.println("This is static initialize block. Will assign the variable name to: mengna");

        System.out.println("Before the name was modified: " + MyTest.name);
        name = "mengna";
        System.out.println("After the name was modified: " + MyTest.name);
    }

    public static String name = "wei.hu";

    public static void main(String[] args) {
        System.out.println(MyTest.name);
    }
}


#結果
This is static initialize block. Will assign the variable name to: mengna
Before the name was modified: null
After the name was modified: mengna
wei.hu

分析:
初始化塊在對靜態變量賦值之前,發現MyTest.name的值為空。 在最后打印出MyTest.name時,發現輸出的值是wei.hu,而不是mengna。也就是說,在初始化塊執行之后,執行了靜態初始化語句。
1、先執行靜態初始化塊;
2、再執行靜態初始化語句;
3、構造函數未執行;
--------------------- 

結論:
對於靜態字段,初始化有如下規則:
1. 若靜態初始化語句在前,靜態代碼塊在后,則先執行靜態初始化語句;
2. 若靜態代碼塊在前,靜態初始化語句在后,則先執行靜態代碼塊;


免責聲明!

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



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