当前位置: 首页 > 面试题库 >

匿名内部类显示不正确的修饰符

周伟泽
2023-03-14
问题内容

据我了解,以下代码应已打印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()));
    }
}

为什么这段代码会这样?


问题答案:

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

15.9.5。匿名类声明:

匿名类永远不会是最终的(第8.1.1.2节)。

匿名类不是最终的事实与强制转换有关,尤其是强制转换操作符允许的缩小引用转换(第
5.5节
)。在子类化中也很有趣,因为尽管匿名类是非最终的,但仍不能声明匿名类的子类,因为匿名类不能由extends子句命名(第8.1.4节)。

JLS 9中引入了这种措辞更改。匿名类的语义和问题中方法的行为基本上保持不变,目的是避免确切地引起该问题的混淆。

导致更改的票证上写着:

从1.3开始,javac的长期行为在大多数情况下一直 将类视为“最终”类。为了解决这种矛盾,应更改规范以准确反映参考实现。

具体来说,几乎不会在设置ACC_FINAL标志的情况下生成匿名类。我们不能在不影响某些序列化客户端的情况下改变这种长期行为(这是允许的,但是不必要地破坏了它)。而且,如果没有类文件对语言的修饰符进行编码的话,我们将无法忠实地实现Class.getModifers(承诺提供“
Java语言修饰符”)。

然而,这种变化 没有 真正改变语义在一定程度上,这也被记录在该票据为可接受的冲击:

更改影响法律程序集,因为它允许某些强制转换在当前规范下被视为非法(请参阅JDK-6219964)。但是,在JLS中搜索“最终”类的提及之后,我预计不会有任何其他影响,这意味着这是与源兼容的修复程序。



 类似资料:
  • 据我所知,以下代码应该已打印为输出。 但是,当我运行此代码时,它正在打印。 来自匿名类15.9.5的Java文档: 匿名类总是隐式最终的 为什么这个代码会这样?

  • 问题内容: 这个问题已经在这里有了答案 : 匿名内部类显示不正确的修饰符 (4个答案) 去年关闭。 据我正确理解 总是: 这已经在 但是,当我运行以下代码来检查它是否显示该类不是。 上面程序的输出是: 请清除我的疑问,因为我无法理解此行为。 问题答案: 显式 是在源代码中写的东西。因此,如果将某些东西声明为,则意味着该类是 明确的final 。 隐式 不是在源代码中写下的,而是在某种构造的上下文中

  • 问题内容: 请看下面的代码: 在上面的代码中,在方法ModifyList()中声明的匿名内部类的实例能够访问传递给该方法的参数。AFAIK Java为内部类创建一个单独的字节码文件。 谁能解释一下Java在字节码级别上如何处理这些局部变量绑定?我的意思是,Java如何精确跟踪对作为参数传递给该方法的对象的引用? 任何帮助将不胜感激! [抱歉我的英语不好! 如果您理解我的问题,请编辑这篇文章,并删除

  • 在以下片段中: 有没有办法从内部匿名类引用匿名类的外部实例? 第二个错误是在解决方案上,我在这里找到了一个匿名内部类的外部类的关键字。这些问题似乎共享一些概念和问题空间,但性质不同。

  • 问题内容: 我正在编写C#Wicket实现,以加深对C#和Wicket的理解。我们遇到的问题之一是Wicket大量使用匿名内部类,而C#没有匿名内部类。 因此,例如,在Wicket中,您可以这样定义一个链接: 由于Link是一个抽象类,因此它强制实现者实现onClick方法。 但是,在C#中,由于没有匿名内部类,因此无法做到这一点。另外,您可以使用如下事件: 当然,这样做有两个缺点。首先,可以有多