Scala has spoiled me, accepting that an if-else doesn’t yield an expression gets harder and harder for me. As my day job is still Java based, I looked for some replacement for
class Foo {
val baz = Map(1->2, 2->3)
}
First step is to javaize it:
class Foo {
val bar = {
val map = new java.util.HashMap()
map put(1,2);
map put(2,3);
map
}
}
And now in Java this can be translated to:
public class Foo {
final Map<Integer,Integer> bar = new Object(){
Map<Integer,Integer> map() {
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
map.put(1,2);
map.put(2,3);
return Collections.unmodifiableMap(map);
}}.map();
}
Why the anonymous class? I could wrap it into a method, but this method must be private, otherwise bad things can happen when the class gets extended (never call non-finals from a constructor). In the anonymous class it is clear that this code serves only this single purpose and is not meant to be used elsewhere; nobody would lightheartly widen the visiblity of this code.
The thing new for some might be that I can call map() on Object. It works on an anonymous calls definition, not elsewhere. Thus you can store away your initializer, if access from a reference it degenerates back to an ordinary object, things that don’t work are:
final Object initializer = new Object() {
String name() { return "MU";}
}
final String name = initializer.name(); //method doesn't exist
and
final String name = new Object() {
Object me() { return this;}
String name() { return "MU";}
}.me()
.name(); // me returns a simple Object, no name() method
Besides the Java clutter, if you can establish it as an idiom it is still fairly readable and expresses well your intent - it is just the syntax imposed by the language which makes it different from the from bit of code. It also helps eliminating non-final variables from a method as you can construct a value completely before exposing it. Of course there is a runtime penalty for the extra Object to be created and collected. The limitations can play for your advantage: The method (why singular?:-) you declared can’t be called elsewhere (unless you use reflection), a “private” method you can call!
Anyway, one question remains: Why did the “return this” idiom heavily used in C++ (at least in my days) out of fashion? In Java you find it in StringBu(ild|ff)er, but rarely elsewhere. Some attempts to create DSLs in Java used it, but besides it seems to be bad style - anyone know some good reason for that? Doing so would allow to write
final Map<Integer,Integer> bar = new HashMap<Integer,Integer>()
.put(1,2)
.put(2,3);
Reflection
If you read so far, here the reflection leak:
Object o = new Object(){
Map<Integer,Integer> map() {
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
map.put(1,2);
map.put(2,3);
return Collections.unmodifiableMap(map);
}};
Method mapFn = o.getClass().getDeclaredMethod("map");
final Map map= (Map) mapFn.invoke(o);
Even more interesting - by this you can pass hidden methods (why plural?:-) through your system - I can imagine even a good use for that: This allows hooks into the defining object so that you can tell where it comes from - worst OO style, but for some intricate manipulation within an API perhaps worth a consideration - or simply an unobstrusive way to to debug with a decorated instance.