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

时间:2009-07-26 00:48:03

标签: java

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

7 个答案:

答案 0 :(得分: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();
    }
}

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

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

答案 1 :(得分: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();
    }
}

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

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

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

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

答案 2 :(得分:3)

本地内部类(除了匿名内部类)只是偶尔有用,虽然我没有任何统计信息。可能绝大多数Java程序员不知道它们存在,所以不打算开始使用它们。

为什么呢?嗯,在匿名内部类和标准内部类之间有一块垫脚石是很好的。事情已经解决了,如果现在只是标准化,我不会指望他们在JLS中。在更新时,虽然新的AWT事件模型密切相关,但新功能的使用经验相对较少。

大多数用途是为同步回调存储一些结果变量。但是,通常只需要通过实例传递给的方法返回一个值,或者使用类似未来的方法。此外,有时您希望在方法中的多个点构造类,但不想丢失闭包功能。

答案 3 :(得分:2)

它允许你有一个构造函数(或几个),并能够在类上调用新方法,并仍然访问在包含方法中声明的最终变量。

值得开销吗?也许不是后见之明,但我认为当时并不是很明显,匿名内部类的限制(没有特定的构造函数,也没有能力在类之外调用新方法)可能只是留在那里而没有另类。

答案 4 :(得分:1)

我假设你的意思是一个匿名的内部阶级?它基本上是一个闭包。您可以将其从方法中传回,并保留变量的范围。它对于Swing中的UI侦听器这样的东西很有用。

答案 5 :(得分:1)

它可用于封装/范围。例如。其余代码不受类定义的污染,其提供的功能仅在该方法中相关。

这些基本上与匿名内部类提供的好处相同,但与匿名内部类相比有一些优势:

  • 可以在方法
  • 中创建多个实例
  • 可以扩展一个类并实现一个或多个接口
  • 可以有一个构造函数

答案 6 :(得分:0)

回答这个问题是一个问题:

如何以这样的方式定义一个类,即只在一个函数中使用该类?例如:A类有2个函数fun1和fun2。你如何定义一个类,以便它只能被fun2使用?

如果在方法之外定义该类,则每个方法都将开始使用它。你如何将它分离出来只用于函数?这可以通过将该类作为该函数的本地内部类来完成。您可以将其视为函数的局部变量,其他函数无法使用它。这个概念也称为增加的安全级别或封装。