I'll be specific: Java 8 is promised to bring lambda expressions as well as method and constructor references among other things. As a Java developer I'm super psyched about that.
In my day to day programming I see more and more opportunities where using these features would greatly simplify code that would otherwise be very verbose and tedious. In lieu of method and constructor references I started using more and more reflection and plan to migrate those code paths to Java 8 as soon as possible. I use special comments (like the well known TODO comments: JAVA8) that can be used by the IDE or grepped easily in order to find the relevant places. I also test all those cases extensively to make sure they work.
But still I have to wonder whether it's good to do it like that. Is it acceptable to produce a little more brittle code now that will eventually become robust again? GA for Java 8 is September 2013 so it's not too far in the future (provided the release date doesn't slip).
A kinda general example would be something like this: I want to create some container objects and fill them with data from a database. If I were to use the standard Java approach, it could look like this:
class ContainerService { private Database database; private final Map, ContainerInitializer> INITIALIZERS = new HashMap(); { INITIALIZERS.put(Foo.class, new FooInitializer()); } public Container getContainer(Class cls) { return INITIALIZERS.get(cls).create(); } interface ContainerInitializer { Container create(); } class FooInitializer implements ContainerInitializer { Container create() { return new Container(database.getFoo()); } } }
The reflective code is
class ContainerService { private Database database; private final Map, String> INITIALIZERS = new HashMap(); { INITIALIZERS.put(Foo.class, "getFoo"); } public Container getContainer(Class cls) { Method m = Database.class.getMethod(INITIALIZERS.get(cls)); return new Container(m.invoke(database)); } }
Note how all the intermediate interfaces and classes fall away.
The Java 8 variant is something along the following lines:
class ContainerService { private Database database; private final Map, ContainerInitializer> INITIALIZERS = new HashMap(); { INITIALIZERS.put(Foo.class, database::getFoo); } public Container getContainer(Class cls) { return new Container(INITIALIZER.get(cls).create()); } private interface ContainerInitializer { Container create(); } }
This is slightly longer again but has type safety. Also it's trivial to get from the prepared code to the final code using method references.
Of course the example is a bit simple. Imagine having a lot of types the container could contain. In the first method, there would be an extra class for each of them. In the other two methods, only data has to be added. It keeps everything so much simpler.