簡體   English   中英

Java靜態初始化行為

[英]Java static initialization behaviour

public class Hello {
        public static final Hello h = new Hello();
        static int i = 5;
        int j  = i;

        private void print() {
            System.out.println(i+" , "+j);

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

            h.print();
        }

    }

這個代碼輸出是5,0。如果原因是靜態加載在類中的第一個並且我被初始化並且j不是。但是如果我從i中刪除靜態也

public class Hello {
        public static final Hello h = new Hello();
        int i = 5;
        int j  = i;

        private void print() {
            System.out.println(i+" , "+j);

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

            h.print();
        }

    }

現在為什么輸出是5,5。 然后當i和j初始化時。 請解釋原因。

靜態塊按順序執行。

首先創建一個Hello對象,此時i = 0因為它尚未設置。

只有在這之后i = 5

您必須從上到下閱讀靜態語句。

在創建Hello對象時,初始化非靜態變量ij

public static final Hello h = new Hello();

對於問題的第一部分, 彼得給了你答案。 讓我補充一下。 如果您更改了靜態變量的順序:

static int i = 5;
public static final Hello h = new Hello();
int j  = i;

它會打印5, 5而不是5, 0

嘗試交換public static final Hello h = new Hello(); static int i = 5; 線。 首先初始化hello對象(when i = 0, uninitialized)i 首先啟動i以獲得預期的行為。

以下是您的第一個示例中發生的情況:

  • 靜態內存初始化為0.此時Hello.i等於0。
  • Hello.h被實例化:
    • Hello.hj初始化為Hello.i的當前值,即0。
  • Hello.i初始化為5。

另一方面,在你的第二個例子中:

  • Hello.h被實例化:
    • Hello.hi初始化為5。
    • Hello.hj初始化為Hello.hi的當前值,即5。

Peter Lawrey的回答是正確的,你的困惑可能來自事實,所有東西都在一個單獨的類中,而名字就是這樣,我想給你另一種方式來形象化你的行為,所以你的代碼在邏輯上等同於下面的代碼:

public class Program {

    public static Hello h = new Hello();

        public static void main(String [] args) {
            h.i = 5;
            h.print();
        }
    }

    class Hello {

        public static int i = 0;
        private int j = i;

        public void print() {
            System.out.println(i+", "+j);
        }
    }

Java在類加載時執行靜態初始化。 因此

public static final Hello h = new Hello();

and default value of when the class is loaded. 在加載類時,創建一個且默認值為的對象。

and non static members, both will have default values for the . 如果同時使變量非靜態成員,則兩者都將具有默認值。

如果在main方法中創建一個新對象

Hello helloObj = new Hello();

它會給你想要的結果。

來自oracle規范的文檔

在類初始化時執行類中聲明的靜態初始化程序(第12.4.2節)。 與類變量的任何字段初始值設定項(第8.3.2節)一起,靜態初始值設定項可用於初始化類的類變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM