Anonymous-Inner классы, показывающие нежелательный модификатор

Насколько я понимаю, следующий код должен был напечатать true.

Однако, когда я запустил этот код, он печатает false.

Из документов Java анонимных классов 15.9.5. :

Анонимный класс всегда неявно завершен

public class Test {
    public static void main(String args[]) {
        Object o = new Object() {
        };
        System.out.println("Annonymous class is final: " + Modifier.isFinal(o.getClass().getModifiers()));
    }
}

Может кто-нибудь, пожалуйста, помогите мне понять это поведение.

Ответы

Ответ 1

Обратите внимание, что формулировка в JLS этого конкретного раздела значительно изменилась с тех пор. Это сейчас (JLS 11) гласит:

15.9.5. Объявления анонимных классов:

Анонимный класс никогда не бывает окончательным (§8.1.1.2).

Тот факт, что анонимный класс не является окончательным, имеет значение при приведении, в частности преобразование сужающих ссылок, разрешенное для оператора приведения (§5.5).Он также представляет интерес для создания подклассов, так как невозможно объявить подкласс анонимного класса, несмотря на то, что анонимный класс не является окончательным, потому что анонимный класс не может быть назван предложением extends (§8.1.4).

Это изменение в формулировке было введено в JLS 9. Семантика анонимных классов и поведение методов в вопросе остались неизменными, целью было избежать именно такой путаницы, о которой идет речь в этом вопросе.

Билет, который вызвал изменение, говорит:

Давнее поведение javac, начиная с версии 1.3, по большей части не относилось к классам как к "финальным". Чтобы устранить это несоответствие, спецификацию следует изменить, чтобы точно отразить эталонную реализацию.

В частности, анонимные классы почти никогда не генерируются с установленным флагом ACC_FINAL. Мы не можем изменить это давнее поведение без влияния на некоторые клиенты сериализации (это было бы допустимо, но излишне разрушительно). И мы не можем точно реализовать Class.getModifers (который обещает предоставить "модификаторы языка Java") без файлов классов, кодирующих модификаторы языка.

Ответ 2

Анонимный класс никогда не бывает final (§8.1.1.2).

JLS 11 - 15.9.5.Объявления анонимных классов

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

Ответ 3

Анонимные классы считаются неявно final поскольку вы не можете создавать их подклассы. Это не означает, что модификатор Modifier.FINAL должен быть установлен для анонимных классов.