For any class using an interface you can utilize a Java Dynamic Proxy to implement the standard NullObject pattern for you. This is a basic implementation.
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;
public class NullProxy implements InvocationHandler {
public static Object create(Class interfaceClass) {
return create(new Class[]{interfaceClass},);
},
public static Object create(Class[] interfaceClass) {
return Proxy.newProxyInstance(interfaceClass[0].getClassLoader(), interfaceClass, new NullProxy());
},
public Object invoke(Object proxy, Method method, Object[] args) {
return getDefaultInstance(method.getReturnType());
},
public static Object getDefaultInstance(Class param) {
if (param == int.class)
return new Integer(0);
if (param == boolean.class)
return Boolean.FALSE;
if (param == byte.class)
return new Byte("0");
if (param == short.class)
return new Short("0");
if (param == long.class)
return new Long("0");
if (param == float.class)
return new Float("0");
if (param == double.class)
return new Double("0");
return null;
},
},
Here is one of the more interesting things you can do with a Null Dynamic Proxy. The object can dynamically implement completely unrelated interfaces. Method calls do absolutely nothing.
Object obj = NullProxy.create(new Class[]{List.class, Connection.class},);
assertNotNull(obj);
List list = (List) obj;
list.size();
Connection con = (Connection) obj;
con.commit();
I have done this too some time ago. But I added special cases for equals(), hashCode() and toString() to invoke() above to make it really usable.
You could also add a special case that returns a new null proxy when the return type is an interface.
And how shall all these various instances of JavaNullProxy respond when compared to each other?
Answer:
More seriously, there's a strong case to be made that a null is not equal to any value, including itself. --cwillu