Search code examples
javalanguage-features

Class inside a block - where would this ever make sense?


I ran over an interesting question yesterday.

The current definition for a Block Statement is here.

BlockStatement: LocalVariableDeclarationStatement ClassDeclaration Statement

This means that you can do something like this

class A {

    public void doIt() {
        class B {}
        B b = new B();
    }
}

or this

public class Test {
    static 
    {
        class C {}
        C c = new C();
    }
}

Good to know that this actually works, but can anybody think of a reasonable use case where you would actually want to do something like this? Where it probably would be the most elegant solution compared to something else?


Solution

  • I imagine you'd do this when extending or implementing a class or interface, where the implementation is very specific to the scope that you're in. Typically you see people doing this with anonymous inner classes, but if you want to get a little more code reuse, while still restricting the class to the scope of the method you're in, you could use one of these local inner classes instead.

    Update

    In many cases, you're going to find that a private static class makes more sense than a local inner class. However, standard practice dictates that we restrict the scope of a class to the narrowest scope that works, to avoid cluttering namespaces and such.

    Also, Java uses local classes to implement/imitate closures. Converting CloseWindowListener in the code below into a private static class would require a lot more code, because you'd have to create a custom constructor and private field to contain the window variable. But because the class is defined within the scope of this method, we can access it directly instead.

    public void setupWindowHandlers(Window window) {
        class CloseWindowListener extends ActionListener {
            public void actionPerformed(ActionEvent event) {
                window.close();
            }
        }
        closeButton.addActionListener( new CloseWindowListener() );
        cancelButton.addActionListener( new CloseWindowListener() );
    }