Friday, March 28, 2008

Initializers in Java

I'm working on slides about language features I'ld like to see in Java. One of them are initializers.
IMHO the lack of this features is the main reason why everybody uses XML. It's just ugly to construct object graphs in an imperative way. Usually such code looks like:

Customer c = new Customer();
c.setName("foobar");
c.setId(4711);

Address address = new Address();
address.setStreet("Schauenburgerstr. 116");
address.setZip("24118");
address.setCity("Kiel");

c.setAddress(address);

Order o1 = new Order();
o1.setArticleId(0815);
o1.setAmount(2);

c.addOrder(o1);

Would be much better if we could specify such a data structure like this:

Customer c = new Customer {
name = "foobar",
id = 4711,
address = new Address {
street = "Schauenburgerstr. 116",
zip = "24118",
city = "Kiel",
},
orders = [new Order {
articleId = 0815;
amount = 2;
}]
};
Actually Java already supports this in some way (not ideal but IMHO better than doing it in a procedural manner). The following code is working Java code:
Customer c = new Customer() {{
name = "foobar";
id = 4711;
address = new Address {{
street = "Schauenburgerstr. 116";
zip = "24118";
city = "Kiel";
}};
addOrder(new Order {{
articleId = 0815;
amount = 2;
}});
}};
The code creates anonymous subclasses with initializers in it. However, as there are no such thing as properties for now you may want to replace the field access by getters and setters. Note that you don't have to make the fields public. So with a combination of getters and protected fields you get immutable types.
Btw.: the same mechanism forks for collections of course:

List l = new ArrayList() {{
add(new Order() {{
setName("stuff");
}});
add(new Order() {{
setName("foo");
setAmount(34);
}});
}};

I'ld still prefer "real" initializers and "real" collection literals, but all in all I think this seems to be a pretty useful idiom.