Double Brace Initialization
Java doesn't have a convenient literal syntax for collections (lists, maps, sets, etc.). This makes creating constant collections or passing collections to functions quite laborious. Every time you have to
1.
Declare a variable for a temporary collection
2.
Create a new empty collection and store a reference to it in the
variable
3.
Put things into the collection
4.
Pass the collection to the method
E.g. To pass a set to a
method:
Set<String> validCodes = new HashSet<String>();
validCodes.add("XZ13s");
validCodes.add("AB21/X");
validCodes.add("YYLEX");
validCodes.add("AR2D");
removeProductsWithCodeIn(validCodes);
Or to initialize a set of
constants:
private static final Set<String> VALID_CODES = new HashSet<String>();
static {
validCodes.add("XZ13s");
validCodes.add("AB21/X");
validCodes.add("YYLEX");
validCodes.add("AR2D");
}
But... you can create and
initialize a new collection as an expression by using the
"double-brace" syntax:
E.g.
private static final Set<String> VALID_CODES = new HashSet<String>() {{
add("XZ13s");
add("AB21/X");
add("YYLEX");
add("AR2D");
}};
Or:
removeProductsWithCodeIn(new HashSet<String>() {{
add("XZ13s");
add("AB21/X");
add("YYLEX");
add("AR5E");
}});
The first brace creates a
new AnonymousInnerClass, the second declares an
instance initializer block that is run when the anonymous inner class is
instantiated. This type of initializer block is formally called an
"instance initializer", because it is declared within the instance
scope of the class -- "static initializers" are a related concept
where the keyword static is placed before the brace that starts the block, and
which is executed at the class level as soon as the classloader completes
loading the class (specified at http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#8.6)
The initializer block can use any methods, fields and final variables available
in the containing scope, but one has to be wary of the fact that initializers
are run before constructors (but not before superclass constructors).
This only works for
non-final classes because it creates an anonymous subclass. Obviously, this is
not limited to collections; it can be used to initialize any kind of object --
for example Gui objects:
add(new JPanel() {{
setLayout(...);
setBorder(...);
add(new JLabel(...));
add(new JSpinner(...));
}});
Comments
Post a Comment