据我了解,以下代码应已打印true
。
但是,当我运行这段代码时,它正在打印false
。
来自Anonymous Classes 15.9.5. 的Java文档:
匿名类始终是隐式终结的
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()));
}
}
有人可以帮我理解这种行为吗?
答案 0 :(得分:48)
请注意,自那时以来,该特定部分的JLS中的措词已发生重大变化。现在(JLS 11)显示为:
15.9.5. Anonymous Class Declarations:
匿名类永远不会是最终的(§8.1.1.2)。
匿名类不是final的事实与强制转换有关,尤其是强制转换运算符(§5.5)允许的缩小引用转换。在子类化中也很有趣,因为尽管匿名类是非最终的,但仍无法声明匿名类的子类,因为匿名类不能由扩展子句(§8.1.4)命名。
这种措辞更改是在JLS 9中引入的。匿名类的语义和问题中方法的行为保持不变,目的是避免确切地引起该问题的混淆。
ticket that caused the change说:
从1.3开始,javac的长期行为在大多数情况下不是 ,而是将类视为“最终”类。为了解决这种矛盾,应更改规范以准确反映参考实现。
具体地说,匿名类几乎不会在设置ACC_FINAL标志的情况下生成。我们不能在不影响某些序列化客户端的情况下改变这种长期的行为(这是允许的,但是不必要地破坏性)。而且,如果没有类文件对语言的修饰符进行编码的话,我们将无法忠实地实现Class.getModifers(它承诺提供“ Java语言修饰符”)。
答案 1 :(得分:9)
匿名类永远不会
final
(§8.1.1.2)。
我不知道其背后的原因,但根据@Hulk的回答和this bug report,似乎以前版本的规范误导了我们说匿名类是最终的。
答案 2 :(得分:8)
因为您不能创建匿名类的子类,所以它们被隐式地视为final
。这并不意味着应该为匿名类设置Modifier.FINAL
修饰符。
答案 3 :(得分:-2)
请参见Class.getModifiers()
的Javadoc:
https://docs.oracle.com/javase/10/docs/api/java/lang/Class.html#getModifiers()
上面写着“ ...其其他修饰符的值不是由本规范确定的”。