Use of class definitions inside a method in Java

bragboy picture bragboy · Mar 11, 2010 · Viewed 79.6k times · Source

Example:

public class TestClass {

    public static void main(String[] args) {
        TestClass t = new TestClass();
    }

    private static void testMethod() {
        abstract class TestMethod {
            int a;
            int b;
            int c;

            abstract void implementMe();
        }

        class DummyClass extends TestMethod {
            void implementMe() {}
        }

        DummyClass dummy = new DummyClass();
    }
}

I found out that the above piece of code is perfectly legal in Java. I have the following questions.

  1. What is the use of ever having a class definition inside a method?
  2. Will a class file be generated for DummyClass
  3. It's hard for me to imagine this concept in an Object Oriented manner. Having a class definition inside a behavior. Probably can someone tell me with equivalent real world examples.
  4. Abstract classes inside a method sounds a bit crazy to me. But no interfaces allowed. Is there any reason behind this?

Answer

Jacob Mattison picture Jacob Mattison · Mar 11, 2010

This is called a local class.

2 is the easy one: yes, a class file will be generated.

1 and 3 are kind of the same question. You would use a local class where you never need to instantiate one or know about implementation details anywhere but in one method.

A typical use would be to create a throw-away implementation of some interface. For example you'll often see something like this:

  //within some method
  taskExecutor.execute( new Runnable() {
       public void run() {
            classWithMethodToFire.doSomething( parameter );
       }
  }); 

If you needed to create a bunch of these and do something with them, you might change this to

  //within some method
  class myFirstRunnableClass implements Runnable {
       public void run() {
            classWithMethodToFire.doSomething( parameter );
       }
  }
  class mySecondRunnableClass implements Runnable {
       public void run() {
            classWithMethodToFire.doSomethingElse( parameter );
       }
  }
  taskExecutor.execute(new myFirstRunnableClass());
  taskExecutor.execute(new mySecondRunnableClass());

Regarding interfaces: I'm not sure if there's a technical issue that makes locally-defined interfaces a problem for the compiler, but even if there isn't, they wouldn't add any value. If a local class that implements a local interface were used outside the method, the interface would be meaningless. And if a local class was only going to be used inside the method, both the interface and the class would be implemented within that method, so the interface definition would be redundant.