Factory using Java Generics


If you want to implement the factory pattern in Java there are many ways to achieve it. But what if you want a factory which may be used for any class?

In Java there is something called Generics which we can use to implement a universal factory in a safe way and eliminating unchecked warnings.

The following code is a snipped example of a Java factory using Generics (it is used in a JavaPOS driver implementation):

public class JposDriverInstanceFactoryImpl
{	
	
	public <E> E createInstance(String logicalName, JposEntry entry, Class typeClass) throws JposException 
	{
    	if (entry.getPropertyValue("driverClass") == null)
        {
            throw new JposException(JposConst.JPOS_E_NOSERVICE, "Missing driverClass JposEntry");
        }    	
    	E driverInstance = null;
        try
        {
            String serviceClassName = (String)entry.getPropertyValue("driverClass");
            Class serviceClass = Class.forName(serviceClassName);
            Class[] params = new Class[0];
            Constructor ctor = serviceClass.getConstructor(params);
            if (typeClass.isInstance(ctor.newInstance((Object[])params)) )
            {
            	//This cast is correct (IMHO) because we are checking the right type
            	//with the method isInstance.
            	@SuppressWarnings("unchecked") E aux = (E)ctor.newInstance((Object[])params);
            	driverInstance = aux;
            }
        }
        catch(Exception e)
        {
        	throw new JposException(JposConst.JPOS_E_NOSERVICE, "Could not create " +
            		"the driver instance for device with logicalName= " + logicalName, e);
        }   
        return driverInstance;
	}
}

We are using the @SuppressWarnings("unchecked") annotation because we can prove that the code provoking this warning is typesafe. Besides we are using the SuppressWarnings annotation on the smallest scope possible, so we are following the nice recomendations that you can find in EJ§Item 24.

The local variable is needed because the SuppressWarnings annotation is not a declaration JLS§9.7.

Get Lucky!!!