6

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.

corsiKa
  • 81,495
  • 25
  • 153
  • 204
  • Would you take "the syntax doesn't allow it"? ;-) That might be why they said "_implicitly_ final"... just guessing. – David Z Dec 21 '11 at 01:20
  • 1
    when compiled they are not anonymous and not private. They still contain metadata though and making them final ensures no super-weird cases (by extending them) – bestsss Dec 21 '11 at 01:20
  • @David, there is a technical reason too – bestsss Dec 21 '11 at 01:20
  • @David no I wouldn't. It seems that it was a deliberate design decision to not allow it. – corsiKa Dec 21 '11 at 01:21
  • @bestsss The fact that they aren't private makes an even stronger case for allowing them to be subclassed. – corsiKa Dec 21 '11 at 01:23
  • Private classes do not exist in java bytecode, they are package private when compiled. The private method/fields accessed by those classes get special accessors, basically `static Foo $accessFieldFoo(OutrerType o)`. Also outher classes should know their inner classes (the metadata), so if extended, that's not possible – bestsss Dec 21 '11 at 01:24
  • 5
    The only way to subclass an anonymous class would be what you showed in your example and that really seems useless. Language design is at least as much about what you leave out than what you put in. I don't see any technical reason (i.e. you could implement it if one really wanted to) to not do it, apart from it adding complexity without any good use case. – Voo Dec 21 '11 at 01:27
  • The main reason why such a thing should not be supported is that it would make your head explode. Dealing with inner classes and anonymous classes in Java is already treading on thin ice, where the designers barely have intellectual control (if they indeed do). No sense in adding a totally unneeded feature that could introduce unforeseen complications. – Hot Licks Dec 21 '11 at 01:31
  • 2
    @Voo *Language design is at least as much about what you leave out than what you put in.* -- Yep, I think someone like Dijkstra said that a few decades back, and it's still true. – Hot Licks Dec 21 '11 at 01:33
  • Like you said, that would be the only way to subclass an anonymous inner class which makes it rather pointless. Consider the alternative. Where would the final keyword go if you had to explicitly make it final? – dspyz Dec 21 '11 at 01:47
  • @dspyz presumably `new final SomeType() { } { }; – corsiKa Dec 21 '11 at 01:53

1 Answers1

6

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.

Luis Casillas
  • 29,802
  • 7
  • 49
  • 102
  • 1
    There are instances, especially in testing code (mocking, spying) where it would be helpful to subclass an anonymous class. – steventrouble Sep 20 '16 at 18:12
  • You are not able to subclass a class you can’t refer by name anyway, whether it is final or not (just like you can’t subclass a class without an accessible constructor). And the most recent specification [changed to say “*an anonymous class is never final*”](https://stackoverflow.com/a/54019398/2711488)… – Holger Jan 10 '19 at 18:04