글
더블 중괄호 초기화
J/Java
2011. 11. 6. 01:37
출처 : http://www.c2.com/cgi/wiki?DoubleBraceInitialization
Double Brace Initialization
One of the JavaIdioms.
JavaLanguage
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
This idea is incompatible with one popular way to implement the equals(Object o) method. Assume class Example has this method:
An idiomatic alternative, that doesn't require such heavy handed use of anonymous inner classes, is to use the constructor arguments to collections that accept another collection as the source data.
- Declare a variable for a temporary collection
- Create a new empty collection and store a reference to it in the variable
- Put things into the collection
- Pass the collection to the 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 withing 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://java.sun.com/docs/books/jls/third_edition/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. This only works only 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(...)); }});The instance of the anonymous class that you have created contain a synthetic reference to the enclosing object. If you serialise the collection you will also serialise everything in the outer class.
This idea is incompatible with one popular way to implement the equals(Object o) method. Assume class Example has this method:
public boolean equals(final Object o) { if (o == null) { return false; } else if (!getClass().equals(o.getClass())) { return false; } else { Example other = (Example) o; // Compare this to other. } }Then, objects created by DoubleBraceInitialization will never be equal to objects created without it. I would never use this for any class that needs a nontrivial equals(Object)method. Collection classes should be fine. So should the JPanel instance above. -- EricJablow It would be nice if Java only created and initialised an instance, not create a new class, for double brace initialisation and any anonymous "class" that does not add fields or override methods.
An idiomatic alternative, that doesn't require such heavy handed use of anonymous inner classes, is to use the constructor arguments to collections that accept another collection as the source data.
List<String> myList = new ArrayList<String>(Arrays.asList("One", "Two", "Three"));Although, this only works with collections that can be represented as a single array -- it doesn't work for maps. Or, use a VarargsCollectionFactoryMethod. >>Although this only works for collections<<< True but but you can use Commons ArrayUtils?.toMap(new MapUtils?.toMap(new String[][] {{
{"RED", "#FF0000"}, {"GREEN", "#00FF00"}, {"BLUE", "#0000FF"}});
'J > Java' 카테고리의 다른 글
자바 키워드 접근자?(수정자??) (0) | 2011.11.10 |
---|---|
SDK, JDK, J2SDK, J2SE, J2EE, J2ME, JRE 용어정리 (0) | 2011.11.09 |
eclipse 단축키 공부하기 (0) | 2011.10.27 |
Java Performance Tip (0) | 2011.10.27 |
[이클립스] 이클립스 실행속도를 올리자! (0) | 2011.10.27 |