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