Lqd's Journal

Icon

It's actually pronounced liquid!

Fun Friday Trick: Generics type inference + static imports = don’t wait for Java 7

Welcome to another fun edition of fun friday on a fun monday.

Today, we’ll see a very simple trick, that uses the regular generics type inference with a factory method and static imports, to make generics more readable.

Reading the java 7 language “pre” proposals (from polls and all), and especially the one about adding more type inference on generic objects construction, i remembered a very simple trick i stumbled upon years ago.

What if you named your factory method as a constructor and imported it using the static import feature ? Turns out, i kinda like how it cleans up the code.

Today, we’re using this, and it’s a mouthful:
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

I think the java 7 proposal (when it’s released, there’s no draft for it yet, only informal polls, and a starting proposal here) will allow to turn it into
Map<String, List<String>> anagrams = new HashMap<>();

First of, notice the ugly empty <>, it would look cleaner without it, but because of backwards compatibility, it might not be “possible”. We’ll see.

While today’s trick turns it into this, (assuming it was added to HashMap of course)

// in java.util.HashMap for instance
// very common code except for the name
public static <K, V> HashMap<K,V> HashMap()
{
   return new HashMap<K, V>();
}

// in your code, where the magic happens
import static java.util.HashMap.HashMap;

// oooh, pretty
Map<String, List<String>> anagrams = HashMap();

It’s less code. It’s cleaner without the <>. It looks a little like a C++ constructor – from a distance (: – , but it has added perks too, it’s a real factory method, so you can verify arguments and throw exceptions *without* creating objects, and so on.

The way we’re doing it today is relatively easy to write since IDEs are helping, so you could see the java 7 proposal as of limited value, but code is written once, and read multiple times. That’s why i think both the proposal and today’s trick have value.

The IDEs are however a little less successfull at providing you intellisense for static imports it seems. You can solve that by modifying the default class template, or by typing HashMap.HashMap() and refactoring it to a static import (or soon will be able to do so).

You don’t have to wait for java 7 for generics to become easier to use, and even though it would be cleaner if the function was in, say, HashMap, you could still have a helper class à la java.util.Collections or google collections’ Lists and Maps, and so on, if you really wanted to.

So, this is really about a way of naming factory methods and importing them statically, making it rather transparent to use today, without waiting for potential language changes. Both are not perfectly clean, but i don’t think we’ll be getting a real clean way (full type inference on the variable) any time soon, so, in the meantime, pick your poison.

Next up: more composite tricks, and the real reason why they might be useful to you. Yes, there is a plan behind the randomness.

Fun Friday: Simple java composite tricks

Welcome to the first fun friday installment, sometimes on a friday i’ll post one of those, and sometimes on a monday instead of friday, just like today.

Out first topic is a very simple trick using transparent proxies, looking nice when implementing Composites – you might have seen it called event sink depending on what kind of composite you’re making. We’ll use a list of instances and a proxy, both of a specified interface which can be any interface you want.

We’ll call a method on that proxy, and under the hood we’ll use that reified call to call the same method but on all the instances of our list, in a somewhat functional style. We’ll just loop over our elements inside the InvocationHandler used by the proxy and invoke the methods on each of them.

The interesting part here is that we can specify the container we’ll use to hold those elements (eg a specific collection – I’ve built an example with a LinkedList; a custom built collection – using Callables – where you can specify your way of creating the collection; or a special thread-safe collection), our own way of looping (from the end or from the beginning of the list; or depending on the type of listeners inside of it, say the ones which are not direct implementors will be called afterwards) and finally our own way of invoking the callback method on each instance (on the regular main thread; on a specified thread, say, EDT *wink*; or why not say that an exception thrown while invoking the callback method will invalidate the listener and remove it from the list of elements). This alllows versatile event handling code here too, and is only a couple hundred lines for the basic support.

Starting from a very simple interface.

public interface IComposite <T>
{
   // you can return void
   //  if you don't want method chaining
   IComposite<T> add (T t);
   IComposite<T> remove (T t);
   
   T delegate();
}

You can gradually build the different composite implementations we just talked about, and get code that looks like this pretty easily (just showing adding one element to the list and slighty reformated for easier reading here, changed some long methods names, etc – the full source is linked at the end of this post)

public class CompositeTest
{
   
// Totally random listener interface
public static interface IListener
{
   void callback ();
}

//Totally random listener interface too:
//  could have been MouseListener for instance
public static interface ISwingListener
   extends EventListener
{
   void callback (String event);
}

public static void main (String [] args)
{

IComposite<IListener> sink = Composites
 .createLinkedListComposite (IListener.class);
sink.add (new IListener()
{
   @Override
   public void callback ()
   {
      System.out.println ("IListener callback ()");
   }
});
sink.delegate().callback();

IComposite<ISwingListener> sink2 = Composites
 .createEventComposite (ISwingListener.class);
sink2.add (new ISwingListener()
{
   @Override
   public void callback (String event)
   {
      System.out.println ("ISwingListener ('"
        + event + "') - on EDT: "
        + SwingUtilities.isEventDispatchThread ());
   }         
});
sink2.delegate().callback ("Main thread test");

// And now with method chaining     
IComposite<ISwingListener> sink3 = Composites
 .createEDTComposite (ISwingListener.class)
 .add (new ISwingListener()
{
   @Override
   public void callback (String event)
   {
      System.out.println ("ISwingListener ('"
        + event + "') - on EDT: "
        + SwingUtilities.isEventDispatchThread ());
   }         
});

sink3.delegate().callback ("EDT dispatch test");

}
}

It’s probably more instructive to do it yourself than using my code, since it’s very small, but here it is anyway (an Eclipse project). You could also imagine special composites that actually use what the callbacks return, like aggregating results or calculating mean min or max values.

See you next friday, monday, soon enough (: