簡體   English   中英

Java實例變量內部和外部構造函數的初始化混亂

[英]Java instance variable initialization inside and outside constructor confusion

讓我們看一小段Java代碼

class Foo {
  int i = 0;
  int j;
  public Foo(int j){
     this.j = j;
  }
}

上面的示例顯示了Java中初始化變量的兩種方法。 但是我的問題是哪個變量首先被初始化? 構造函數外部的變量還是構造函數內部的變量? 當我實例化上面的類Foo foo = new Foo(5) ,我知道該類的構造函數被調用,這意味着變量j首先被初始化。 誰能讓我清楚訂購的信息。

優先順序

在您的情況下, int j首先發生並且默認為0 ,然后在構造函數被調用以創建新實例時重新分配為5

j僅在構造函數運行時重新分配。 當您在構造函數之外分配實例成員時,實例成員首先被初始化。

執行命令

每行代碼都按其顯示順序執行。 聲明總是按照代碼中列出的順序在構造函數之前發生。

確定性和可預測性

您只應在單個構造函數中的單個位置初始化實例成員。

依賴默認值會導致難以跟蹤錯誤,並使測試成為噩夢,但是未分配的實例成員會像對IDE,編譯器和運行時的煩惱一樣脫穎而出。 不幸的是,對於像int這樣的基元,它們默認為0 ,這可能不是您想要/不需要的。

更好的設計是:

 private final int j;

 public Foo(final int j) { this.j = j; }

這樣可以避免在初始化時為j分配任何東西,而您不必擔心它會發生變化。

假設您有這堂課

public class Test
{
    int i = 4;

    public Test()
    {
        System.out.println(i);
    }  
}

創建Test的實例時,輸出為4 這意味着初始化首先進行。 然后調用構造函數。 因為如果構造函數是第一個,而i的初始化是第二個,則不會得到4作為輸出。

int i = 0;

我是一個實例變量,因此將獲得默認值0。因此,您無需顯式分配0。

來問你的問題

 But my question is which variable first get initialized?

然后答案是i在j之前初始化。 因為如果您看到代碼段的字節碼,則首先創建對象,這將初始化您的實例變量,然后調用構造函數。

無論何時創建對象創建,都會先進行變量的聲明,然后才定義變量。 在您的情況下,將首先聲明“ j”變量,即類變量。此后,該值將在類的構造函數中分配給“ j”。

訂購:-

  1. 首先執行靜態初始化塊。(如果有)
  2. 然后從main方法開始執行。

對於您的問題,我認為當i=0ij將會一起出現。 j為0(具有int默認值。)

因為在構造函數中,您只是在更改值。

暫無
暫無

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

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