java - 显示不正确修饰符的匿名内部类
问题描述
据我了解,以下代码应该已打印true
为输出。
但是,当我运行此代码时,它正在打印false
.
匿名类总是隐式最终的
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()));
}
}
为什么这段代码的行为是这样的?
解决方案
请注意,从那时起,该特定部分的 JLS 中的措辞发生了重大变化。现在 (JLS 11) 内容如下:
匿名类永远不会是最终的(§8.1.1.2)。
匿名类不是 final 的事实与强制转换有关,特别是强制转换运算符允许的缩小引用转换(第 5.5 节)。子类化也很有趣,因为尽管匿名类是非最终的,但不可能声明匿名类的子类,因为匿名类不能由扩展子句命名(第8.1.4 节)。
这种措辞的变化是在 JLS 9 中引入的。匿名类的语义和问题中方法的行为基本保持不变,其目的是避免这个问题所涉及的那种混淆。
导致更改的票证说:
自 1.3 以来,javac 的长期行为在大多数情况下一直不将类视为“最终”。为了解决这种不一致,应该更改规范以准确反映参考实现。
具体来说,匿名类几乎不会在设置 ACC_FINAL 标志的情况下生成。我们无法在不影响某些序列化客户端的情况下改变这种长期存在的行为(这是允许的,但会造成不必要的破坏)。如果没有对语言修饰符进行编码的类文件,我们就无法忠实地实现 Class.getModifers(它承诺提供“Java 语言修饰符”)。
但是,该更改确实在一定程度上改变了语义,并且这也被记录在此票证中作为可接受的影响:
该更改会影响合法程序集,因为它允许一些在当前规范下被视为非法的强制转换(请参阅JDK-6219964)。但是,在 JLS 中搜索“最终”类的提及后,我预计不会有任何其他影响,这意味着这是一个与源代码兼容的修复程序。
推荐阅读
- javascript - Chrome 开发工具的性能面板中的文档和文档框架计数是多少?
- javascript - PHP 中的条件格式 JavaScript
- javascript - 出现某些情况时显示警报错误消息
- android - 为什么android从编译转向实现
- python-3.x - Jinja 中的 For 循环无法再次使用或如何移动 First
- git - SSH 是有状态的还是无状态的?
- python - 如何在 Python 中平滑概率分布图?
- numpy - 调用 polyfit 时将 for 循环移动到 numpy 单个表达式中
- python - Ubuntu 18.04 无法打开软件和更新
- javascript - 错误:使用 Renderer2 创建 Angular 服务时出现 StaticInjectorError(AppModule)[SomeComponent -> Renderer2]