8

Got to know that we can initialize a collection in java by using double brace initialization. And did some search on that and found that it is not advised to use it because of its performance issue.

private static final Set<String> VALID_CODES = new HashSet<String>() {{
    add("XZ13s");
    add("AB21/X");
    add("YYLEX");
    add("AR2D");
 }};

Just want to know, is there any positive side or advantage of DOUBLE BRACE INITIALIZATION??

Raja Asthana
  • 2,080
  • 2
  • 19
  • 35
  • No, only positive side is less code.. but not readable to all other who are not aware of double brace initialization. – Phani Jan 31 '13 at 13:17
  • 2
    Although more readable by people who can program in Java, in a non-static context you are going to pick up a reference to the enclosing `this`. You may also pick up fixed references to final fields that you use when calling the mutators. That wont be obvious to most Java programmers, and may well lead to obscure memory issues. // Anyway, you should be writing something like `private static final Set VALID_CODES = Collections.unmodifiableSet(new HashSet(Arrays.asList("XZ13s", "AB21/X", "YYLEX", "AR2D")));`, obviously. – Tom Hawtin - tackline Jan 31 '13 at 13:34

2 Answers2

6

not advised to use it because of its performance issue.

I don't see any performance issue. Whenever you see someone say I did/didn't do something for performance reason you should expect to see detailed analysis comparing the alternatives explaining how one met the specific required performance and the other did not. If you don't see all this you might assume the author is just guessing.

EDIT: While I will concede each class takes a small amount of time to load, the running performance is exactly the same. I have demonstrated here https://stackoverflow.com/a/14627268/57695

I would use double brace notation if you believe it's simpler and clearer.

A disadvantage is that your are changing the type of the collection which can confuse functions where that is not expected. e.g. equals.

Note: As Lukas Eder points out, you want to be careful if you do this in a non-static context. The anonymous sub-class collection will implicitly have a reference to the outer instance and if it lives longer than the collection, this would be a memory leak. Have you ever thought of the possibility of a memory leak?

Community
  • 1
  • 1
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 1
    The question [Efficiency of Java “Double Brace Initialization”?](http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization) actually talked about the performance issue, and it *is* slower. – Alvin Wong Jan 31 '13 at 13:19
  • 2
    @AlvinWong That test seems to be fairly broken - in particular, whenever I see a test returning "0 ms", my first guess is that the code has not been run (which would be totally legal in that case because the results are never used). Also the JVM is not warmed up properly... I would not trust those results. – assylias Jan 31 '13 at 13:22
  • The top answer on the above thread has some comments questioning the performance measurements – Brian Agnew Jan 31 '13 at 13:22
  • @peter: I read like Double Brace Initialization creates an anonymous inner class and also creates a separate .class file after compiling. Also there were more examples states that it takes more time to execute when compare to the normal collection which is initialized in static block. – Raja Asthana Jan 31 '13 at 13:22
  • @assylias - seconded re. the 0ms measurement – Brian Agnew Jan 31 '13 at 13:22
  • So, the advantage of using this is 'simpler' and 'clearer'. Not more than that. – Raja Asthana Jan 31 '13 at 13:29
  • 1
    @AlvinWong It takes longer to load them. If you have 1000 anonymous classes you have a problem anyway, but even so it added 185 ms to load them all. or 185 micro-seconds each. If you believe 185 micro-second on the startup of your application is critical, you might avoid it.... – Peter Lawrey Jan 31 '13 at 13:30
  • 1
    @RajaAsthana If you believe it is simpler or clearer which is a matter of taste. ;) I have used it some times but it can be over used as well. – Peter Lawrey Jan 31 '13 at 13:51
  • 2
    Peter, extending HashMap/Set may force Class Hierarchy Analysis beside the need to do the IO. More also cost of loading classes is not always trivial - lets say, in multi-tiered classloaders structure (application servers, esp w/ RMI classloading enabled!), i.e. each delegates to the parent (has to), searches through the JAR/file system, bail-out back till the current classloader finally loads the anon. class. Again microbenchmarks are not sufficient to prove a case. Imo, "double brace" nonse is just a truly bad practice. – bestsss Feb 02 '13 at 10:32
  • @bestsss It is also worth noting that double braced class can make class unloading trickier if the object is retained. – Peter Lawrey Feb 02 '13 at 10:48
  • Yeah, the 'original' question about, I mention that. It can be a hidden classloader leak. – bestsss Feb 02 '13 at 10:52
  • Peter, [Have you ever thought of the possibility of a memory leak?](http://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/) – Lukas Eder Dec 17 '14 at 08:47
  • @LukasEder good point. I will update the answer to note that you should be careful in non-static contexts. – Peter Lawrey Dec 17 '14 at 09:26
  • Thanks for the mention. I've actually run into such a memory leak in the past because I thought I could just remove `static` on a method in order to be able to override it. Bad idea :-) – Lukas Eder Dec 17 '14 at 10:18
  • 1
    @LukasEder If you have OSGi and a subclassed thread local (not technically double braced but similar) you can have the problems that an entire module is being held due to a thread local (which might not be needed, but the thread is still running) This can prevent you unloading the module and upgrading it. – Peter Lawrey Dec 17 '14 at 10:23
  • 1
    @PeterLawrey: You have always been good at discovering almost unreal edge cases :-) – Lukas Eder Dec 17 '14 at 10:30
3

There's no particular performance issue (beyond the cost of loading a class via the classloader - negligible)

The above does create an anonymous class and as such it contains an implicit this reference to the surrounding instance. That can cause some confusion for serialisation frameworks. e.g. you serialise the anonymous class you've created, and you suddenly find you're also trying to serialise the containing instance.

I would highlight that anonymous classes can be used a lot under the covers in different frameworks and indeed languages (Scala - I'm looking at you). I've never heard anyone suggest that Scala has issues with performance due to classloading. Initial startup may be fractionally slower, but bear in mind JVM startup, JIT warmup, any network access etc.

You might argue that your application footprint is bigger, due to more classes. I suspect (again) the effect is negligible (unless you construct a whole application out of anonymous classes!)

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440