Tuesday, September 14, 2010

Java Language Puzzle 1

From the domain of stuff that makes you wonder if your debugger is lying to you, I give you a little puzzle. How many times does the following code print the line “Creating crumble…” and why?

public class JavaLanguagePuzzle1
{
    private static abstract class CookieBase
    {
        public CookieBase()
        {
            init();
        }
        
        protected void init() {}
    }
    
    private static class Cookie extends CookieBase
    {
        private Crumble crumble = null;

        protected void init()
        {
            crumble();
        }
        
        public Crumble crumble()
        {
            if( this.crumble == null )
            {
                this.crumble = new Crumble();
            }
            
            return crumble;
        }
    }
    
    private static class Crumble
    {
        public Crumble()
        {
            System.err.println( "Creating crumble..." );
        }
    }
    
    public static void main( final String[] args )
    {
        ( new Cookie() ).crumble();
    }
}

SOLUTION: Pretty much everyone who responded came up with the correct answer of two times. Most correctly explained why that happens. Part of the reason is that explicit member variable initialization in a class happens after the superclass constructor has executed. The part that might be tricky to realize is that explicitly initializing a member variable to null does not have the same runtime behavior as leaving it uninitialized. Removing explicit initialization of crumble to null makes this code behave as it appears to on the surface.