Java Hack: Double Brace Initialization
refactory.org
refactory.org
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.
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.(The caching is for the very common case of creating a subclass with optional roles applied:
my $class = Some::Meta::Class->create_anon_class(
superclasses => ['Foo'],
roles => [qw/Commonly Applied Traits/],
);
There is almost no speed hit the second time you create an instance of "Foo" with "Commonly", "Applied", and "Traits" applied. Not sure this would be useful for Java, although we can achieve the same effect as in the article.)I like this trick though, it will help me with my seaside clone in java :)
There is something to be said for not baking things into the language.
List<int> intList = new List<int>() { 1, 2, 3 };
which involves no anonymous classes or anything of the sort. The compiler merely "expands" it into the following before producing the bytecode: List<int> intList = new List<int>();
intList.Add(1);
intList.Add(2);
intList.Add(3);
Which is, really, about what I'd expect such a shortcut syntax to do. List<Integer> list = Arrays.asList(1,2,3,4,5);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.
Lists.newArrayList(1, 2, 3)
Or, if you don't need to modify it: ImmutableList.of(1, 2, 3)
Such an awesome library. 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);