

Java Hack: Double Brace Initialization - smokestack
http://www.refactory.org/s/double_brace_initialisation/view/latest

======
ZitchDog
Watch out - double-brace initialization is cool looking, but it's orders of
magnitude slower than regular initialization as it must generate an anonymous
class.

Also, the generated class is put into the permgen space, which is not garbage
collected. The permgen is pretty small by default - and if you fill it up,
your system is hosed.

I use them all the time in unit tests, but never in production code.

~~~
scotth
The compiler generates the anonymous class. To the runtime, isn't it just a
class with a name given to it by the compiler, not a developer (question
mark...my key broke today)

It's true that it uses up permgen though, but if it only adds an initializer
we're not talking about much space.

Edit:

I did an experiment. This is the code:

    
    
         new ArrayList<Object>() {
           {}
         };
         new ArrayList<Object>();
    

Here is the bytecode:

    
    
         0  new Main$1 [16]
         3  invokespecial Main$1() [18]
         6  new java.util.ArrayList [19]
         9  invokespecial java.util.ArrayList() [21]
    

And, the class:

    
    
        class Main$1 extends java.util.ArrayList {
    
        // Method descriptor #6 ()V
        // Stack: 1, Locals: 1
        Main$1();
          0  aload_0 [this]
          1  invokespecial java.util.ArrayList() [8]
          4  return
        Line numbers:
          [pc: 0, line: 10]
          [pc: 4, line: 1]
        Local variable table:
          [pc: 0, pc: 5] local: this index: 0 type: new Main(){}
    

Just a regular old subclass.

~~~
elcron
You can always copy and paste a question mark (?). I don't recommend coding
that way, I once tried coding with the left quarter of the keyboard broken,
not fun.

~~~
cdr
alt + keypad 63 works too (at least on Windows)

------
fi0660
For initializing lists there is a less verbose expression in Java:

    
    
      List<Integer> list = Arrays.asList(1,2,3,4,5);

~~~
akeefer
. . . except that doesn't get you a modifiable list, it just wraps a List
interface around the array that's implicitly created by the var-arg, so it's a
trick you have to be careful with.

Personally I often end up writing little helpers like: List<T> list(T... args)
{ return new ArrayList<T>(Arrays.asList(args)) } usually in test code. A
built-in List and Map-initialization syntax is really something every decent
programming language ought to have.

~~~
litewulf
(Consider using the Google collections library if possible. It already has
that in the form of classes like Lists, Maps, etc that provide builders and
factory methods.)

------
duncanj
Nice. Could have used that thought about 9 years ago :)

------
codahale
This is where Google Collections comes in handy:

    
    
        Lists.newArrayList(1, 2, 3)
    

Or, if you don't need to modify it:

    
    
        ImmutableList.of(1, 2, 3)
    

Such an awesome library.

------
eldenbishop
I've been using this for years. It is a fantastic way to build up hierarchies.
XML, maps, JSON, UI code etc. It is very concise, fast and produces clean code
which also just happens to correctly indent when you apply code formatting.

    
    
      School s = new School() {{
        add(new Student() {{
          name = "Bobby";
          age = 15;
          add(new Pet() {{
            name = "Fluffy";
          }});
        }});
      }};
    
      vs.
      School sc = new School();
      Student st = new Student();
      st.name = "Bobby";
      st.age = 15;
      Pet p = new Pet();
      p.name = "Fluffy";
      st.add(p);
      sc.add(st);

------
eldenbishop
One thing though. I love this technique but the home built Eclipse compiler is
not fully Java language compliant and it will reject certain forms of this as
invalid. Specifically, the sun and eclipse compiler treat "this" differently
in these code blocks. My project will not compile under eclipse because of
certain usages of this pattern when combined with inner classes. The bug crops
up when you need to pass the parent to the child object being initialized in
the static block.

