[concurrency-interest] Joda-Time immutability

Peter Jones pcj at roundroom.net
Mon Jun 20 14:02:53 EDT 2011

On Jun 20, 2011, at 1:32 PM, Stephen Colebourne wrote:

> On 20 June 2011 17:52, Attila Szegedi <szegedia at gmail.com> wrote:
>> Well, to me it looks like it's implemented:
>> import java.lang.reflect.Field;
>> public class TestFinalField {
>>   public final int x = 1;
>>   public static void main(String[] args) throws Exception {
>>     TestFinalField tff = new TestFinalField();
>>     Field f = tff.getClass().getField("x");
>>     f.setAccessible(true);
>>     f.set(tff, 2);
>>     System.out.println(tff.x);
>>   }
>> }
>> This prints "1", and not "2". So, setting of a final field is actually
>> silently ignored with setAccessible(true), for better or worse. Without
>> setAccessible(), it will actually throw an exception. With the "final"
>> qualifier removed from the field, it prints "2", as expected. I tested it
>> with both latest Java 6 and on the b145 build of OpenJDK 7, and both behaves
>> as described.
> Well thats weird, because my change works and passes the tests in Joda-Time.
> https://github.com/JodaOrg/joda-time/commit/067983f2684fa9e9ca4af4ef73b09e2be2f70001#diff-8
> Anyone know what is going on? Can this be sufficiently relied on? I
> haven't really got a workable alternative.

In the above case, because the field is initialized with a compile-time constant, the value must be inlined at regular accesses at compile time-- see JLS chapter 13, look for "constant variables".  Printing "f.get(tff)" should show that the field's value has in fact changed, even though code compiled with "tff.x" won't notice.  But I would guess that the instance fields you care about aren't initialized with constants.

-- Peter

More information about the Concurrency-interest mailing list