Anonymous classes are not final according to reflection API

Remi Forax forax at
Thu Jul 2 22:25:29 UTC 2015

Hi Dan,

You can not set a serialVersionUID of an anonymous class because a 
serialVersionUID is a static final field which you can not declare 
inside an anonymous class.
That's said the name of an anonymous class is not stable too.

and to answer your question about who is using getModifiers() on a class,
a lot of tools that generate proxies at runtime (Hibernates, Weld etc) 
because if the class is not final,
you can generate a class that inherits from it.


On 07/03/2015 12:10 AM, Dan Smith wrote:
>> On Jun 29, 2015, at 7:57 AM, Maurizio Cimadamore <maurizio.cimadamore at> wrote:
>> I think this should be fixed so that anon classes (regardless of their context) always have their ACC_FINAL bit unset; this is probably not very hot from a compatibility perspective (given that it's been like that for a long time) - but, given the consistency issue and the fact that reflection cannot handle this anyway, I'd say we should just make this consistent.
> If we're making a change to which flags are set, we might as well do it properly and make them all final, no?  One way or another, you're going to change some serialization UIDs.
> Really, javac is free to implement anonymous classes however it likes (with a few small constraints from JLS, notably in Chapter 13).  If it wants to spell all the synthetic field names backwards on Tuesdays, that's it's business.  Anybody relying on certain conventions for serialization between recompiled anonymous classes is playing a risky game, and they should not be surprised if things break from time to time.*  (Some smaller examples that would also change some UIDs: different bridge generation strategies; different methods produced by lambda/method reference compilation; refining the implementation of asserts; improvements in diamond inference.)
> That said, I get the practical constraint of not rocking the boat if there's not a compelling need to do so.  And it's notable that this would impact a lot more UIDs than the typical bug fix.
> However:
> - The JLS assertion "An anonymous class is always implicitly final" is meaningless if it's not interpreted as "the ACC_FINAL flag on the generated class is set", so if we're not going to enforce that, the assertion should be dropped.  (The other assertions in 15.9.5 have language-level implications, but not this, since none of the corresponding language restrictions in could ever arise.)
> - I don't know why reflection is colluding with javac here.  Dynamically changing flags seems to pretty directly violate the Class.getModifiers spec.  Does the computation of serialVersionUID rely on reflection?  If so, doesn't this flag-modification logic belong there, rather than breaking reflection for everyone?  If not, who's relying on the reflection behavior?
> —Dan
> [* It's "strongly recommended", in italics no less, not to rely on this.  From java.lang.Serializable: "it is _strongly recommended_ that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization"]

More information about the compiler-dev mailing list