JavaMemoryModel: Update on final fields in JVMS

From: Bill Pugh (
Date: Wed Jul 21 2004 - 08:32:55 EDT

OK, just to revisit, Gilad wanted to relax the JVMS semantics for final
fields, so that the verifier wouldn't have to check that each final
field is assigned exactly once.

In looking at various ways to relax it, Doug and I agreed that allowing
a constructor for class X to change the final fields of any instance of
class X is too relaxed. Instead, in a constructor for class X, the only
final fields you should be able to change are the final fields of the
instance being constructed. (Also, in class X, you can only change
final fields declared in class X, not final fields in any super or
subtype of X).

The proposed text in the specification of putfield is:
> If the field is final, the putfield must occur in an <init> method of
> the class that declares the final field, and the objectref parameter
> to the putfield instruction must be the this argument to the <init>
> method. Otherwise, an
> {\tt IllegalAccessError}

The problem with this is that checking this can be difficult, and could
possibly require a runtime test. For example, consider:

class A {
   final int x;
   A(A a, boolean b) {
     A a2 = b ? this : a;
     a2.x = 42;

Do we want to allow invocations of new A(null,true) to succeed?
The rule I proposed above requires that
new A(new A(null,true), false) fail.

In general, if the bytecode has been obfuscated/optimized, we might not
be able
to count on the fact that local 0 contains a reference to the object
being constructed.

In all (almost all?) cases involving unobfuscated code, a trivial
static check can be used
to verify that the assignment to the final field is correct.

As I mentioned, Doug and I are really unhappy with the idea of allowing
a constructor to change
the final fields of any instance of the class. And I think the
requirements for enforcing this rule
can be handled.


JavaMemoryModel mailing list -

This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:01:08 EDT