Anonymous-Inner 类 显示不正确的修饰符

Anonymous-Inner classes showing incorrect modifier

根据我的理解,下面的代码应该打印 true 作为输出。

但是,当我 运行 这段代码正在打印时 false

来自 Anonymous Classes 15.9.5. 的 Java 文档:

An anonymous class is always implicitly final

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()));
    }
}

为什么这段代码会这样?

匿名 类 被隐含地视为 final,因为您无法创建它们的子 类。这并不意味着应该为匿名 类.

设置 Modifier.FINAL 修饰符

An anonymous class is never final (§8.1.1.2).

JLS 11 - 15.9.5. Anonymous Class Declarations

我不知道这背后的原因,但是,根据@Hulk 的回答和 this bug report,似乎以前版本的规范稍微误导了我们说匿名 类 是最终的。

请注意,自那时以来,该特定部分的 JLS 中的措辞发生了重大变化。现在 (JLS 11) 显示:

15.9.5. Anonymous Class Declarations:

An anonymous class is never final (§8.1.1.2).

The fact that an anonymous class is not final is relevant in casting, in particular the narrowing reference conversion allowed for the cast operator (§5.5). It is also of interest in subclassing, in that it is impossible to declare a subclass of an anonymous class, despite an anonymous class being non-final, because an anonymous class cannot be named by an extends clause (§8.1.4).

这种措辞上的变化是在 JLS 9 中引入的。匿名的语义 类 和问题中方法的行为大部分保持不变,目的是避免这种问题的混淆关于。

ticket that caused the change 说:

Longstanding behavior of javac, since 1.3, has been, for the most part, not to treat the classes as 'final'. To address this inconsistency, the specification should be changed to accurately reflect the reference implementation.

Specifically, anonymous classes are almost never generated with the ACC_FINAL flag set. We can't change this longstanding behavior without impacting some serialization clients (this would be permissible, but is unnecessarily disruptive). And we can't faithfully implement Class.getModifers (which promises to provide the "Java language modifiers") without the class files encoding the language's modifiers.

但是,更改 确实 实际上在某种程度上改变了语义,这也被记录在这张票中作为可接受的影响:

The change impacts the set of legal programs, in that it allows some casts that would be considered illegal under the current specification (see JDK-6219964). But, after searching for mentions of 'final' classes in JLS, I don't anticipate any other impact, meaning that this is a source-compatible fix.

请参阅 Class.getModifiers() 的 Javadoc: https://docs.oracle.com/javase/10/docs/api/java/lang/Class.html#getModifiers()

它说“...它的其他修饰符的值不是由这个规范决定的”。