为什么所有匿名类都是隐式最终的?

发布于 2024-12-22 08:59:14 字数 800 浏览 5 评论 0原文

根据 JLS 的说法:

15.9.5 匿名类声明 匿名类声明是通过以下方式自动从类实例创建表达式派生的: 编译器。

匿名类从来都不是抽象的(第 8.1.1.1 节)。匿名类是 始终是内部类(第 8.1.3 节);它永远不是静态的(§8.1.1,§8.5.2)。 匿名类始终是隐式最终的 (§8.1.1.2)

这似乎是一个特定的设计决定,所以它很可能有一些历史。

如果我选择这样的类:

SomeType foo = new SomeType() {
    @Override
    void foo() {
        super.foo();
        System.out.println("Hello, world!");
    }
};

如果我这样选择,为什么不允许我再次对其进行子类化?

SomeType foo = new SomeType() {
    @Override
    void foo() {
        super.foo();
        System.out.println("Hello, world!");
    }
} {
    @Override
    void foo() {
        System.out.println("Hahaha, no super foo for you!");
    }
};

我并不是说我一定想要,或者甚至可以想到我会这样做的理由。但我很好奇为什么会这样。

According to the JLS:

15.9.5 Anonymous Class Declarations An anonymous class declaration is automatically derived from a class instance creation expression by the
compiler.

An anonymous class is never abstract (§8.1.1.1). An anonymous class is
always an inner class (§8.1.3); it is never static (§8.1.1, §8.5.2).
An anonymous class is always implicitly final (§8.1.1.2).

This seems like it was a specific design decision, so chances are it has some history.

If I choose to have a class like this:

SomeType foo = new SomeType() {
    @Override
    void foo() {
        super.foo();
        System.out.println("Hello, world!");
    }
};

Why am I not allowed to subclass it again if I so choose?

SomeType foo = new SomeType() {
    @Override
    void foo() {
        super.foo();
        System.out.println("Hello, world!");
    }
} {
    @Override
    void foo() {
        System.out.println("Hahaha, no super foo for you!");
    }
};

I'm not saying I necessarily want to, or can even think of a reason why I would. But I am curious why this is the case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你的笑 2024-12-29 08:59:14

好吧,能够子类化匿名类是毫无用处的。您能够引用匿名类的唯一位置是在定义它的语句中(如假设的伪代码示例所示)。这意味着程序将保证永远不会创建匿名超类的任何实例,并且智能编译器应该能够将两个定义折叠到一个类中。

更实际的是,当一个类是最终类时,编译器和虚拟机可以自由地在调用站点内联其方法。因此,在任何自然不可能扩展给定类的情况下,使此类类本质上是最终的是有意义的。

Well, it would be pretty useless to be able to subclass an anonymous class. The only spot where you would be able to refer to the anonymous class would be in the statement where it's defined (as your hypothetical pseudocode example shows). This means that the program would be guaranteed never to create any instances of the anonymous superclass—and that a smart compiler should be able to collapse the two definitions into one class.

More practically, when a class is final, compilers and VMs are free to inline its methods at the calling sites. So in any situation where it is naturally impossible to extend a given class, it makes sense to make such classes intrinsically final.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文