Woozle Wuzzle
Constructor exceptions

Here's a real noodle scratcher when you first encounter it. This makes a good interview question since it forces candidates to talk through the construction sequence. This isn't a question that I would necessarily expect someone to answer correctly but I would expect someone to be able to talk through the various cases and the effects of those cases.

/**
 * <p>Tests that refernces can be made to an member even though its constructor 
 * fails.</p>
 */
public class ConstructorExceptionTest extends TestCase
{
    /**
     * <p>Tests that refernces can be made to an member even though its 
     * constructor fails.</p>
     */
    public void testException()
    {
        final ArrayList<ConstructorException> objects = new ArrayList<ConstructorException>();
        ConstructorException failedObject = null;  
        try
        {
            failedObject = new ConstructorException(objects);
        } catch(final Exception e)
        {
            // ignore since it is required to occur
        }
        assertNull("The newly created member should be null.", failedObject);
        assertTrue("The list should not be empty.", !objects.isEmpty());

        final ConstructorException listObject = objects.get(0);
        assertNotNull("References to the object still exist.", listObject);
        assertNull("The object's member should be null.", listObject.member);
    }

    /**
     * <p>An member that throws an exception on construction to ascertain what
     * ooccurs to references to it that are made before the construction 
     * completes.</p>
     */
    private class ConstructorException
    {
        /**
         * <p>Some member that is "created" after the constructor should have
         * failed.</p>
         */
        final Object member;

        /**
         * <p>Adds itself to the specified list of objects before it throws an
         * exception.</p>
         * 
         * @param  objects a list of objects to which this member adds itself
         * @throws Exception always
         */
        public ConstructorException(final List<ConstructorException> objects)
            throws Exception
        {
            objects.add(this);
            if(true)
                throw new Exception();
            /* else -- cannot occur */

            member = new Object();
        }
    }
}

I should point out to all of you doubting Thomas' out there that this test runs green. I should also point out that the if(true) is a trivial replacement for anything that can go wrong during construction.

Logging and throwing exceptions

I was getting tired of remembering to have to log my exceptions and I wanted something to do it for me. I remembered something about generics and exceptions. This is what I came up with:

/**
 * <p>A convenience method for 
 * {@link org.apache.log4j.Logger#error(java.lang.Object, java.lang.Exception) logging}
 * and throwing the specified {@link java.lang.Exception}.</p>
 *
 * <p>Example usage:</p>
 * 
 * <pre>
     private void someMethod()
         throws SomeException
     {
         ...
         LogException.logThrow(log, new SomeException("This will be logged and thrown."));
         ...
     }
 * <pre>
 * 
 * @param  log the <code>Logger</code> to which the exception is logged.
 * @param  exception the <code>Exception</code> to be logged and <code>throw</code>n
 * @throws E the specified exception
 */
public static <E extends Exception> void logThrow(final Logger log, 
                                                  final E exception)
    throws E
{
    log.error(exception, exception);
    throw exception;
}

The only obvious problem with this technique is that the compiler doesn't know the method never returns normally. So in a case such as:

public int returnInt()
    throws SomeException
{
    final int value;
    try
    {
        value = ....
    } catch(final OtherException e)
    {
        LogException.logThrow(log, e);
    }
    return value;
}

the compiler will complain that value may not have been initialized. Oh well. I can dream can't I?

Creative Commons License Unless otherwise expressly stated, all original material of whatever nature created by Rob Grzywinski and included in this weblog and any related pages, including the weblog's archives, is licensed under a Creative Commons License.