Почему все анонимные классы неявно являются окончательными? - PullRequest
6 голосов
/ 21 декабря 2011

Согласно JLS:

15.9.5 Объявления анонимного класса Объявление анонимного класса автоматически выводится компилятором из выражения создания экземпляра класса.

Анонимный классникогда не абстрагируйтесь (§8.1.1.1).Анонимный класс всегда является внутренним классом (§8.1.3);оно никогда не статично (§8.1.1, §8.5.2). Анонимный класс всегда неявно является окончательным (§8.1.1.2) .

Похоже, это было конкретное проектное решение, поэтому есть вероятность, что у него есть история.

Если я выберу такой класс:

SomeType foo = new SomeType() {
    @Override
    void foo() {
        super.foo();
        System.out.println("Hello, world!");
    }
};

Почему мне не разрешается подкласс, если я так решу?

SomeType foo = new SomeType() {
    @Override
    void foo() {
        super.foo();
        System.out.println("Hello, world!");
    }
} {
    @Override
    void foo() {
        System.out.println("Hahaha, no super foo for you!");
    }
};

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

1 Ответ

6 голосов
/ 21 декабря 2011

Ну, было бы довольно бесполезно иметь возможность создавать подкласс анонимного класса. Единственное место, где вы сможете ссылаться на анонимный класс, - это оператор, в котором он определен (как показывает пример вашего гипотетического псевдокода). Это означает, что программе гарантированно никогда не будет создаваться никаких экземпляров анонимного суперкласса, и что умный компилятор должен иметь возможность свести два определения в один класс.

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

...