Anonymous-Inner классы, показывающие нежелательный модификатор - PullRequest
0 голосов
/ 03 января 2019

Насколько я понимаю, следующий код должен был печатать 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()));
    }
}

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

Ответы [ 4 ]

0 голосов
/ 03 января 2019

См. Javadoc Class.getModifiers(): https://docs.oracle.com/javase/10/docs/api/java/lang/Class.html#getModifiers()

В нем говорится " ... Значения других его модификаторов не определяются этой спецификацией ".

0 голосов
/ 03 января 2019

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

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

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

0 голосов
/ 03 января 2019

Обратите внимание, что формулировка в 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») без файлов классов, кодирующих модификаторы языка.

0 голосов
/ 03 января 2019

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

...