You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-dev@db.apache.org by cbeams <cb...@gmail.com> on 2007/09/21 22:31:54 UTC
Support for final modifier on fields
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
Re: Support for final modifier on fields
Posted by cbeams <cb...@gmail.com>.
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