簡體   English   中英

實例初始化器和構造函數之間有什么區別?

[英]What's the difference between an instance initializer and a constructor?

只是想知道編譯代碼的原因是這樣的:

class MyClass extends AnotherClass {
  {
    MySecondClass object = new MySecondClass();
    object.doSomething();
  }
}

這個代碼和構造函數中的代碼有什么區別? 此代碼對象創建之前執行。

沒有名稱的大括號內的代碼將成為類的構造函數的一部分,並在類構造函數中包含的邏輯之前執行。

快速舉例:

public class Foo {
    {
        System.out.println("Before Foo()");
    }

    public Foo() {
        System.out.println("Inside Foo()");
    }

    {
        System.out.println("Not After Foo()");
    }
}

這稱為實例初始化程序。 在初始化代碼中調用父類的構造函數和構造函數代碼的其余部分之前 插入。

任何構造函數的第一個操作是調用超類構造函數。 如果顯式調用構造函數super(...) ,則使用指定的構造函數。 如果沒有顯式調用構造函數,則在超類中調用默認構造函數(不帶參數)。 如果不存在這樣的構造函數,則是編譯時錯誤。

在此顯式或隱式構造函數調用之后,將按照它們在源代碼中出現的順序調用實例初始值設定項(是的,您可以使用多個初始值設定項)。

為了說明,運行此程序打印

Another constructor
Init 1
Init 2
Test constructor
class Another {
  Another() { System.out.println("Another constructor"); }
}

class Test extends Another {

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

  { System.out.println("Init 1"); }

  Test() { System.out.println("Test constructor"); }

  { System.out.println("Init 2"); }

}

最常見的應用程序是initalization中的“雙括號初始化”習慣用法,其中定義了匿名內部類,並且一次創建和配置實例。 這是Swing編程中一個相當常見的例子:

JButton popupButton = new JButton(new AbstractAction("Popup") {
  {
    putValue(Action.SHORT_DESCRIPTION, "Popup a dialog");
  }

  @Override
  public void actionPerformed(ActionEvent evt)
  {
    popup();
  }
});

如果您有多個構造函數,並且需要在每個構造函數中執行一些無參數初始化,這可能很有用。 這可以作為初始化塊的因素。

這是一個構造函數之前運行的實例初始化塊 ,如果你問為什么要用它代替構造函數呢? 答案是否定的,你沒有。

只是想知道編譯代碼的原因是這樣的:

在使用構造函數重載時,通常使用它來分解公共代碼。 因此,上面的“ the ”實際上是指執行公共實例初始化代碼塊之后在對象實例化時調用的重載構造函數之一。

順便說一句,你有時可以通過調用另一個構造函數來實現相同的功能,但調用必須在調用構造函數的第一行,否則代碼將無法編譯。

暫無
暫無

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

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