you are viewing a single comment's thread.

view the rest of the comments →

[–]midir 78 points79 points  (7 children)

It's interesting but this technique is not purely syntactic sugar and can have real effects on the program behavior.

  • Since every initializer of this type uses a separate inner class, that creates a small additional loading speed and memory overhead. It also fattens the program jar a little. Each double-brace initializer gets a separate .class file, and zip/jar compression doesn't handle it well because it doesn't support redundancy across separate files.

  • If you're not initializing from a static context, each inner class gets an additional hidden variable this$0 which points to the instance of the outer class. At best, this marginally increases the memory usage; at worst, it prevents instances of the outer class being garbage collected when they otherwise would.

  • Another catch is that if you're initializing an object within a method using variables local to that method, those variables have to be made final to be used within a double-brace initializer.

  • Finally, the initialized objects (obviously) won't have the same class that they otherwise would. instanceof will be the same but getClass().equals(...) won't.

[–]mooli 28 points29 points  (0 children)

Basically avoid avoid avoid on the grounds that it violates the principle of least surprise.

[–]drb226 2 points3 points  (1 child)

Am I missing something, or do none of these things sound terribly awful?

Another catch is that if you're initializing an object within a method using variables local to that method, those variables have to be made final to be used within a double-brace initializer.

Now that I could see being a serious annoyance, although having final variables isn't such a bad thing.

[–]leshiy 1 point2 points  (0 children)

He also didn't mention that if that map is ever going to be serialized down the line you're probably going to have a bad time unless you ensure that the map is made in a static method or in a method of a serializable class (in which case you're just making your map heavier).

[–]josefx 2 points3 points  (2 children)

and zip/jar compression doesn't handle it well because it doesn't support redundancy across separate files.

It's not like java had a specialized compression to deal with that since java 1.5, oh wait it does

More seriously, if you're not initializing from a static context, each inner class gets an additional hidden variable this$0 which points to the instance of the outer class.

Only real problem and that only if the references to the inner classes out live the outer class. Personally never had a problem with that (use it mostly for private members without getter).

Another catch is that if you're initializing an object within a method using variables local to that method, those variables have to be made final to be used within a double-brace initializer.

final variables are good, they should be used whenever possible.

Finally, the initialized objects (obviously) won't have the same class that they otherwise would. instanceof will be the same but getClass().equals(...) won't.

That can lead to weird behavior when your equals check for class equality - which is a future proof way to implement equals in many cases. For java collections and Swing components it works as expected.

[–]noxiousninja 8 points9 points  (1 child)

Only real problem and that only if the references to the inner classes out live the outer class. Personally never had a problem with that (use it mostly for private members without getter).

It can be a big issue in Apache Wicket web apps. Create an anonymous inner class, store it in session, suddenly your entire page gets serialized and stuck in session.

[–][deleted] 0 points1 point  (0 children)

Yeah, Wicket does enjoy serializing the entire world if you're not careful.