?

Log in

No account? Create an account
 
 
16 November 2006 @ 03:18 pm
Java initialization recipe  
I, like many other developers used to more dynamic languages, have often been frustrated with code that first initiales something, then goes through a long sequence of steps to get it into the initial state.

Map data = new HashMap();
data.put("Hello", "world");
data.put("Spam", eggs");


In Python, Perl, Ruby, JavaScript, and many other languages you can logically create a mapping and set its values in a "one-liner". Even if this actually spans several lines, this "initial state" code is cleanly separated from any business logic within the same method. Inline definition also helps for setting up complicated objects as static values or class properties, without relying on a constrcutor or other bootstrapping at a separate location in the code.

One interesting solution for Java I recently saw on a mailing list uses a feature that has been present in Java since 1.2: anonymous inner classes. Our example now becomes:

Map data = new HashMap() {{
  put("Hello", "world");
  put("Spam", "eggs");
}};


Note that this technique works for almost any Object, so it is also useful for "initializing" a Java Bean:

Example e1 = new Example() {{
  setHello("world");
  setSpam("eggs");
}};


Once you are familiar with the recipe, this is actually much more clear and informative than multi-argument constructors in Java.

This actually works by defining a new class inline as a subclass of HashMap or Example or whatever. Within the anonymous subclass you can override the contents of that class - usually by overriding methods. This technique is usually used in AWT programming to create event handlers.

Additionally, you can provide "initializers" - which is where the extra set of curly braces come from. Initializers are rarely used in Java - they are anonymous blocks of code within a Java class that are executed AFTER the class constructor but BEFORE the class instance is returned to the caller. Theoretically, any constructor code that is not dependant on Constructor parameters can be moved out into an initializer, allowing that code to be reused for every constructor, but I hardly ever see Java code use this feature.

I wish I had seen this a year or two ago. It probably would have saved Lana from trying to maintain some of the hacks I wrote at Pharmacy OneSource.
 
 
 
Stupendous Man: Picard mouthfarmalloc on November 17th, 2006 07:15 am (UTC)
That is awesome!
(Anonymous) on March 26th, 2007 02:46 pm (UTC)
Thanks
Thank you, very much.

Miguel Lienlaff
mlienlaff@sii.cl