简体   繁体   中英

Java: Creating an instance of a local inner classes

Below, is some toy code that demonstrates my question. The first one is a version that compiles, and the second is a version that does not compile.

In example 1 , in order to create an instance of InnerClass, I must create the instance below the class definition of InnerClass. This makes sense, because above the class definition, InnerClass is not visible. However, lets say for the sake of neatness, I want to create and use an instance of InnerClass at the top of foo(). Is there a way to define InnerClass on the fly before the actual class definition, such that my code could look more like example 2 but would be legal Java?

example 1

public class OuterClass {
    public void foo() {
        class InnerClass {  

            public InnerClass() {
                // do nothing.
            }

        }

        InnerClass in = new InnerClass(); // Defined below, and compiles!

    }
}

example 2

public class OuterClass {
    public void foo() {

        InnerClass in = new InnerClass(); // Defined above, does not compile!

        class InnerClass {  

            public InnerClass() {
                // do nothing.
            }

        }

    }
}

Conceptually, local class declaration is a statement. The class doesn't exist until the statement is executed. The class also disappears when the scope it's declared in ends. In general a local class may reference other local scope names, so execution ordering is important.

void f()
{
  if(true) 
      throw new Error();

  class InnerClass
  { 
    ... 
  }
}

In this example, InnerClass declaration statement is never reached, so the class will never exist. Referencing it beforehand would be meaningless.

It's always a good idea to declare something before using it. In Java classes can have circular dependencies so Java must allow referencing classes out of blue - but don't do it if it can be avoided.

You can define the inner class outside of the method like

public class OuterClass {
    public void foo() {

        InnerClass in = new InnerClass(); // Defined above, does not compile!


    }

    class InnerClass {  
        public InnerClass() {
            // do nothing.
        }
    }
}

Sounds like a lot of work just for the sake of neatness. Here is a trick using an anonymous inner class that lets you declare an instance of a class that has functionality you haven't defined yet, which is kind of similar to what you want.

Note the limitation is that you have to have defined the interface somewhere earlier or reuse an existing interface like Runnable. Here is an example:

public class OuterClass {
    public void foo() {
        // Declaration
        Runnable anonymous;

        // Implementation
        anonymous = new Runnable() {
            public void run() {
                // do nothing.
            }
        };

        // Execution
        anonymous.run();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM