Класс внутри блока - где это будет иметь смысл? - PullRequest
2 голосов
/ 10 июля 2011

Вчера я столкнулся с интересным вопросом .

Текущее определение для Block Statement: здесь .

BlockStatement: LocalVariableDeclarationStatement ClassDeclaration Statement

Это означает, что вы можете сделать что-то подобное

class A {

    public void doIt() {
        class B {}
        B b = new B();
    }
}

или это

public class Test {
    static 
    {
        class C {}
        C c = new C();
    }
}

Приятно знать, что это действительно работает, но кто-нибудь может придумать разумный вариант использования, когда вы действительно захотите сделать что-то подобное?Где это, вероятно, будет самым элегантным решением по сравнению с чем-то еще?

Ответы [ 2 ]

2 голосов
/ 10 июля 2011

из Effective Java 2nd Edition:

Если вам нужно создать экземпляры из только одно место и нет ранее существовавший тип, который характеризует класс, а затем сделать его локальным классом.

2 голосов
/ 10 июля 2011

Я полагаю, что вы будете делать это при расширении или реализации класса или интерфейса, где реализация очень специфична для вашей области действия. Обычно вы видите, как люди делают это с анонимными внутренними классами , но если вы хотите получить немного больше повторного использования кода, при этом ограничивая класс областью действия метода, в котором вы находитесь, вы можете использовать один из этих локальных внутренних классов вместо этого.

Обновление

Во многих случаях вы обнаружите, что закрытый статический класс имеет больше смысла, чем локальный внутренний класс. Однако стандартная практика требует, чтобы мы ограничивали область действия класса самой узкой областью действия, чтобы избежать загромождения пространств имен и тому подобного.

Кроме того, Java использует локальные классы для реализации / имитации замыканий . Преобразование CloseWindowListener в приведенном ниже коде в закрытый статический класс потребовало бы гораздо больше кода, поскольку вам нужно было бы создать собственный конструктор и закрытое поле, содержащее переменную window. Но поскольку класс определен в рамках этого метода, мы можем получить к нему прямой доступ.

public void setupWindowHandlers(Window window) {
    class CloseWindowListener extends ActionListener {
        public void actionPerformed(ActionEvent event) {
            window.close();
        }
    }
    closeButton.addActionListener( new CloseWindowListener() );
    cancelButton.addActionListener( new CloseWindowListener() );
}
...