Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meaning of new Class(...){{...}} initialization idiom [duplicate]

What does {{ ... }} block mean in the following code?

class X {

    private Y var1;

    private X() {
        Z context = new Z(new SystemThreadPool()) {{
            var1 = new Y();
        }};
    }

}
like image 942
Victor Sorokin Avatar asked Sep 03 '09 08:09

Victor Sorokin


4 Answers

It's called double curly brace initialization. (EDIT: Link removed, archived here)

It means you're creating an anonymous subclass and the code within the double braces is basically a constructor. It's often used to add contents to collections because Java's syntax for creating what are essentially collection constants is somewhat awkward.

So you might do:

List<String> list = new ArrayList<String>() {{
  add("one");
  add("two");
  add("three");
}};

instead of:

List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");

I actually don't like that and prefer to do this:

List<String> list = Arrays.asList("one", "two", "three");

So it doesn't make much sense in that case whereas it does for, say, Maps, which don't have a convenient helper.

like image 187
cletus Avatar answered Nov 04 '22 18:11

cletus


The "outer" braces mean that you're making an anonymous subclass, the second braces are the object initializer. The initializer is run before the class' constructor, but after any super calls (and therefore also after any superclass initializers). You can use initializers in non-anonymous classes, too, which is a convenient way to initiate final fields if you have several constructors which cannot call each other, or fields which need more complex initialization than usual field initializers allow.

Consider this class:

class X extends Y{
    private final int lulz;

    private static boolean someCondition(){...}
    private static boolean danger() throws SomeException { ... }
    public X(A a) throws SomeException {
        super(a); 
        lulz = someCondition()? danger() : 0;
    }
    public X(B b) throws SomeException {
        super(b); 
        lulz = someCondition()? danger() : 0;
    }
}

It could be rewritten as:

class X extends Y{
    private final int lulz;

    private static boolean someCondition(){...}
    private static boolean danger() throws SomeException { ... }
    { // initalizer -- might throw SomeException!
        lulz = someCondition()? danger() : 0;
    }
    public X(A a) throws SomeException { super(a); }
    public X(B b) throws SomeException { super(b); }
}

If the initializer can throw a checked exception, all constructors must declare they can throw it.

like image 25
gustafc Avatar answered Nov 04 '22 16:11

gustafc


You are creating an anonymous class and using the class Instance initializer idiom, like this:

class X {
    private Y var1;

    private X() {
        Z context = new Z(
               new SystemThreadPool()) {
                   {                        // This is the initialize idiom
                       var1 = new Y();      //
                   }                        //
               }
          );  // BTW you are missing ")"
    }
}
like image 4
David Santamaria Avatar answered Nov 04 '22 16:11

David Santamaria


As mentioned in previous answers, double curly brace initialization is correct.

It uses a specific technique to Initializing Instance Members in Java. It is a shorthand way for defining in a class definition, a shared block of code that will run when any of the class constructor is activated.

I am adding the link to the official Java documentations describing it for more broader view on the subject.

From the documentation:

Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:

{

// whatever code is needed for initialization goes here 

}

The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.

like image 3
elpddev Avatar answered Nov 04 '22 18:11

elpddev