1. 程式人生 > 程式設計 >Java靜態和非靜態成員變數初始化過程解析

Java靜態和非靜態成員變數初始化過程解析

這篇文章主要介紹了Java靜態和非靜態成員變數初始化過程解析,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

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

非靜態變數

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

  • 成員變數初始化語句;
  • 成員變數初始化塊;
  • 建構函式;

示例一:

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)最後執行了建構函式;

結論:

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

初始化語句、初始化塊,總是先於建構函式執行;

初始化語句、初始化塊的和執行順序,取決於 初始化語句、初始化塊在程式碼中的書寫順序。寫在上面的先執行。

靜態變數

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

  • 靜態初始化語句;
  • 靜態初始化塊;
  • 建構函式;

示例一:

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. 若靜態程式碼塊在前,靜態初始化語句在後,則先執行靜態程式碼塊;

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。