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

前端 未结 3 1870
走了就别回头了
走了就别回头了 2020-12-10 01:19

Just wondering about the reason of compiling code like this:

class MyClass extends AnotherClass {
  {
    MySecondClass object = new MySecondClass();
    obj         


        
相关标签:
3条回答
  • 2020-12-10 01:59

    The code inside the braces with no names will be part of the constructor of the class and be executed before the logic contained in the class constructor.

    Quick example:

    public class Foo {
        {
            System.out.println("Before Foo()");
        }
    
        public Foo() {
            System.out.println("Inside Foo()");
        }
    
        {
            System.out.println("Not After Foo()");
        }
    }
    
    0 讨论(0)
  • 2020-12-10 02:05

    This is an instance initialization block that runs before the constructor and if you ask why would one wanna use it in place of the constructor? The answer is no, you don't.

    Just wondering about the reason of compiling code like this:

    You usually use it to factor out common code when using constructor overloading. So, the "the" above actually refers to one of the overloaded constructors that gets called on object instantiation after the common instance initialization code block has executed.

    By the way, you could sometimes achieve the same by calling one constructor from the other but the call then has to be on the first line inside the calling constructor or the code won't compile.

    0 讨论(0)
  • 2020-12-10 02:15

    This is called an instance initializer. The code in the initializer is inserted after the call to the super class constructor and before the rest of the constructor code.

    The first operation of any constructor is to invoke a super class constructor. If a constructor is called explicitly, super(...), the specified constructor is used. If no constructor is explicitly invoked, the default constructor (with no arguments) is invoked in the super class. If no such constructor exists, it is a compile time error.

    After this explicit or implicit constructor invocation, instance initializers are invoked in the order they appear in source code (yes, you can have more than one initializer).

    To illustrate, running this program prints

    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"); }
    
    }
    

    The most commonly seen application is in the initalization the "double brace initialization" idiom, where an anonymous inner class is defined, and an instance is created and configured at once. Here's a fairly common example from Swing programming:

    JButton popupButton = new JButton(new AbstractAction("Popup") {
      {
        putValue(Action.SHORT_DESCRIPTION, "Popup a dialog");
      }
    
      @Override
      public void actionPerformed(ActionEvent evt)
      {
        popup();
      }
    });
    

    This could be useful if you have multiple constructors, and need to perform some parameter-less initialization in every constructor. This could be factored into an initialization block.

    0 讨论(0)
提交回复
热议问题