在实践中使用本地 class

Using local class in practice

我们什么时候应该使用本地类? 最佳实践方法?

是否可以将它们抽象或静态化?

还有其他解决方案可以避免吗?

来自 document :

As mentioned in the section Nested Classes, nested classes enable you to logically group classes that are only used in one place, increase the use of encapsulation, and create more readable and maintainable code. Local classes, anonymous classes, and lambda expressions also impart these advantages; however, they are intended to be used for more specific situations:

Local class: Use it if you need to create more than one instance of a class, access its constructor, or introduce a new, named type (because, for example, you need to invoke additional methods later).

Anonymous class: Use it if you need to declare fields or additional methods.

Lambda expression:

  • Use it if you are encapsulating a single unit of behavior that you want to pass to other code. For example, you would use a lambda
    expression if you want a certain action performed on each element of
    a collection, when a process is completed, or when a process
    encounters an error.
  • Use it if you need a simple instance of a functional interface and none of the preceding criteria apply (for example, you do not need a
    constructor, a named type, fields, or additional methods).

Nested class: Use it if your requirements

  • are similar to those of a local class, you want to make the type more widely available, and you don't require access to local variables or method parameters.

  • Use a non-static nested class (or inner class) if you require access to an enclosing instance's non-public fields and methods. Use a static nested class if you don't require this access.

您可以在方法体、for 循环或 if 子句中定义局部 class。它们类似于 Inner class,因为它们不能定义或声明任何静态成员。

它们也是非静态的,因为它们可以访问封闭块的实例成员。

另请阅读此 document 以了解本地 类。

局部 class 很像局部变量。如果 class 仅在单个方法中有用,您将创建一个本地 class。

它们可以声明为抽象的,但不能声明为静态的。如您所料,静态方法中的局部 class 无法访问封闭 class.

的非静态实例字段或方法

没有理由回避它们,如果它们正确而干净地帮助您完成任务。

我发现的一个用途是构建 Swing 菜单栏层次结构:

private JMenuBar buildMenuBar() {

    class MenuAction extends AbstractAction {
        private static final long serialVersionUID = 1;

        @Override
        public void actionPerformed(ActionEvent event) {
            // Deliberately empty.
        }
    }

    Action fileMenuAction = new MenuAction();
    Action editMenuAction = new MenuAction();
    Action viewMenuAction = new MenuAction();
    Action helpMenuAction = new MenuAction();

    localizer.configure(fileMenuAction, "menu.file");
    localizer.configure(editMenuAction, "menu.edit");
    localizer.configure(viewMenuAction, "menu.view");
    localizer.configure(helpMenuAction, "menu.help");

    JMenu fileMenu = new JMenu(fileMenuAction);
    JMenu editMenu = new JMenu(editMenuAction);
    JMenu viewMenu = new JMenu(viewMenuAction);
    JMenu helpMenu = new JMenu(helpMenuAction);

    // etc.
}

没有其他方法需要 MenuAction class,所以我把它放在 buildMenuBar 方法的本地。