方法本地内部类的用途是什么?

and*_*and 18 java

为什么Java的设计者认为它有用/必要?

sta*_*lue 16

由于大多数人可能从未见过方法本地内部类,这里有一个例子:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

理论上,当一个匿名类因为需要多个实例而无法使用时,它可以作为内部类下面的附加封装级别.也许如果你需要在不同的方法中说出不同的比较器,并且需要不止一次地实例化它们.这似乎非常罕见(我以前从未写过这样的类),而使用普通的内部类并不是什么大问题.

因此,在我看来,将它包含在一种新设计的语言中是不值得的.


Gre*_*ill 7

使用方法本地类可以通过将相关部分保持在一起来提高代码的可读性.作为一个人为的例子,假设您有一个方法需要创建一个线程来在后台执行某些操作:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果没有方法本地类,则必须:

  • 在里面创建一个新的命名类Test来进行后台处理,或者
  • 单独的源文件中创建一个新的命名类来进行后台处理.

这两个选项都可以通过在源树中的其他位置移动相关处理来降低代码的可读性(可能在同一个源文件中,可能完全在另一个源文件中).使用方法本地类将处理逻辑保持在使用它的位置.

这当然不适用于所有情况,但在许多常见情况下它非常有用.这样的代码通常用于GUI动作侦听器,这是非常小的类,通常只是将动作方法调用从一个地方中继到另一个地方.

  • 这个例子是一个匿名的内部类. (15认同)