Why are all anonymous classes implicitly final?

2019-02-22 07:14发布

问题:

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.

回答1:

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.