A bit more on this topic. It looks like the post-construction
mutability of final fields was a change made in Java 5 per JSR-133.
Heinz Kabutz goes deeply into it here: http://www.javaspecialists.eu/
archive/Issue096.html
He even specifically calls out:
"It makes sense to allow updates to final fields. For example, we
could relax the requirement to have fields non-final in JDO."
Definitely give the article a read... interesting stuff.
- Chris
On Sep 21, 2007, at 1:31 PM, cbeams wrote:
I'd like to point out a minor inconsistency in the spec (that
actually caused me some trouble), as well as suggest a change:
Section 6.2, "Goals" reads:
6.2 Goals
The JDO Object Model has the following objectives:
• All class and field modifiers supported by the Java language
including private,
public, protected, static, transient, abstract, final,
synchronized, and volatile, should be supported by JDO
instances.
Having read this, I expected that I should be able to define fields
within my PC classes as final, and everything would be OK.
This, however, is not true because of section 18.15:
Fields with modifier final: none. Accessors will be generated for
these fields during
enhancement, but they will not delegate to the StateManager.
And is further explained in 22.10.2:
22.10.2 Final
A20.10.2-1 [Final fields are treated as non-persistent and non-
transactional by the enhancer.] Final
fields are initialized only by the constructor, and their values
cannot be changed after construction
of the instance. [Therefore, their values cannot be loaded or
stored by JDO; accesses are not medi-
ated. This assertion is duplicated in chapter 18.]
This treatment might not be what users expect; therefore, final
fields are not supported as persistent
or transactional instance fields, final static fields are supported
by ignoring them.
"Bummer", thought I.
So, first of all, I'm suggesting that we at least modify 6.2 to
call out the exception to the rule, explicitly stating that final
fields are not supported.
Preferably, however, I suggest we change the spec to support final
fields. The statement in 22.10.2 that reads "final fields are
initialized only by the constructor, and their values cannot be
changed after construction of the instance" is actually incorrect.
Reflecting on a final field and calling setAccessible(true) does in
fact render it mutable to the caller. This is all an
implementation needs to do!
There's also the question of bytecode enhancement and the addition
of a no-arg constructor; it would be reasonable for the enhancer to
simply create a constructor that sets all the final fields to null;
it's going to write over them anyway.
Perhaps I've missed something here, but I think the spec is just
incorrect on this matter, and it would serve users well to support
final on fields. It was a huge disappointment for me when I first
found out JDO didn't allow for this, as I use final liberally to
ensure proper object construction.
Thanks,
- Chris Beams