What's the use of a method-local inner class?

Since most people probably have never seen a method-local inner class, here is an example:

public class TestMethodLocalInnerClass
{
    public static void main(String[] args)
    {
        class Greeter implements Runnable
        {
            private final String _greeted;

            public Greeter(String greeted)
            {
                super();
                _greeted = greeted;
            }

            public void run()
            {
                System.out.printf("Hello %s!\n", _greeted);
            }
        }

        new Greeter("world").run();
        new Greeter("dog").run();
    }
}

This could theoretically be useful as an additional level of encapsulation below an inner class when an anonymous class can't be used because you need more than one instance. Maybe if you need say different comparators in different methods and need to instantiate them more than once. This seems to be very very rare (I never wrote such a class before), and it is not a big deal to use normal inner classes instead.

So in my view it would not be worth to include it in a newly designed language.


Using method-local classes can increase the readability of your code by keeping related parts together. As a contrived example, suppose you have a method that needs to create a thread to do something in the background:

class Test {
    void f() {
        // Method local inner class
        class InnerClass {
            private String myThreadName;
            // InnerClass constructor
            public InnerClass(String myThreadName) {
                this.myThreadName = myThreadName;
            }
            // InnerClass method
            public void run() {  
                Thread thread = new Thread(
                    // Anonymous inner class inside method local inner class
                    new Runnable() {
                        public void run() {
                            doSomethingBackgroundish();
                        }
                    }
                );
                thread.setName(myThreadName);
                thread.start();
            }
        }
        InnerClass anInnerClass = new InnerClass(aThreadName);
        anInnerClass.run();
    }
}

Without method-local classes, you would have to either:

  • create a new named class inside Test to do the background processing, or
  • create a new named class in a separate source file to do the background processing.

Both these options can reduce the readability of the code by moving the related processing somewhere else in your source tree (maybe in the same source file, maybe in another source file entirely). Using a method-local class keeps the processing logic right where it is used.

This is certainly not applicable for all situations, but it can be very useful in a number of common situations. Such code is commonly used for GUI action listeners, which are very small classes that usually just relay action method calls from one place to another.


Local inner classes (other than anonymous inner classes) are only occassionally useful, although I don't have any statistics for you. Probably the vast majority of Java programmers don't know they exist, so aren't about to start using them.

Why? Well, it is nice to have a stepping stone between an anonymous inner class and a standard inner class. The way things have worked out, I wouldn't expect them to be in the JLS if it was just being standardised now. At the time of the update, there had been relatively little experience with the new features, although the new AWT event model was intimately linked.

Most uses are to store some result variable for synchronous callbacks. However, typically you would just have a value returned through the method the instance was passed to, or use something like a future. Also, sometimes you want to construct the class at more than one point within the method, but don't want to lose the closure features.

Tags:

Java