Brian's Waste of Time

Mon, 23 Aug 2004

Picocontainer Null Object Builder

Charles Miller pointed out that passing null instead of a null object would just as happily generate an exception. I like to be explicit though, especially when cheating and purposefully not providing a component implementation. As promised in the comments, here is a much fancier null component builder (and testcase) than you'll ever really need ;-)

package org.skife.picotools;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class NC
    private static class NCHandler implements InvocationHandler
        private final Class iface;

        NCHandler(final Class iface)
            this.iface = iface;

        public Object invoke(final Object proxy,
                             final Method method,
                             final Object[] args) throws Throwable
            final StringBuffer signature = new StringBuffer();
            final Class[] params = method.getParameterTypes();
            for (int i = 0; i != params.length; i++)
                final Class param = params[i];
                if (i != params.length - 1) signature.append(", ");
            signature.append("): ")
            throw new IllegalStateException(new StringBuffer()
                                            .append("Invoked method [")
                                            .append(" on null component implementing [")

    public static Object build(final Class iface)
        return Proxy.newProxyInstance(iface.getClassLoader(),
                                      new Class[]{iface},
                                      new NCHandler(iface));

package org.skife.picotools;

import java.util.Map;
import junit.framework.TestCase;

public class NCTest extends TestCase {
    public void testThing() {
        final Map null_map = (Map);
        try {
            null_map.put("key", "value");
            fail("Should have thrown excpetion");
        } catch (IllegalStateException e) {
            assertTrue("Go through here", true);

Exception message will look like Invoked method [java.util.Map#put(java.lang.Object, java.lang.Object): java.lang.Object] on null component implementing [java.util.Map]

Easy, and the error is much more explicit than a null pointer exception. Admittedly, (WombatDAO) is 21 keystrokes more than (WombatDAO)null but we are using Java here, not Perl =)

2 writebacks [/src/java] permanent link