re: JavaMemoryModel: final, pseudo-final and write protected fields

From: Paul Haahr (haahr@jivetech.com)
Date: Thu Oct 21 1999 - 17:42:05 EDT


Doug Lea wrote, quoting himself (who I had agreed with):
> > My take on this is that language/vm treatment of final are too weak.
> > I think this code compiles and loads due to limitations in the
> > compile/verify checks, not by any other intent. Probably the best
> > solution would be to fix the compiler and verifier (and their specs)
> > to be more conservative here, outlawing all potential reads before
> > writes of finals -- which would in particular disallow all non-static
> > method calls on this before values are set.
>
> Oh, now I remember these issues.
>
> If you conservatively disallow all method calls (and other uses of
> "this") before final assignments in constructors, then a lot of
> subclass constructors become illegal.

Right. I had also forgotten about calls to subclass-overridden methods
in constructors, which I think need to enable reading of uninitialized
finals. E.g.:

  class A {
    int x;
    A() {
      x = f();
    }
    int f() {
      return 42;
    }
  }

  class B extends A {
    final int y;
    B() {
      super();
      y = 13;
    }
    int f() {
      return y;
    }
  }

It seems unavoidable to me that (new B()).x == 0, though it does seem a
bit unfortunate, but I can't come up with a sane rule for Java which
would prohibit that case but allow ``seemingly reasonable'' uses. (We
did have such semantics for Dylan, but they made the general case of
uninitialized values very slow and very ugly.)

But, so what? As Doug notes:

> Still, it seems like a bad idea to establish any sort of guarantees in
> cases where people misuse finals. A disclaimer saying that all bets
> are off if the non-assigned value of a final is ever accessed sounds
> reasonable to me. Better static analysis tools could help programmers
> avoid such cases.

I'd still prefer a rule which prohibited the use of ``this'' before all
blank final variables have been initialized, along the lines of this
restriction from JLS 8.6.5:

  An explicit constructor invocation statement may not refer to any
  instance variables or instance methods declared in this class or any
  superclass, or use this or super in any expression; otherwise, a
  compile-time error occurs.

It doesn't catch all cases, as we've noted, but it's simple enough to
understand, explain, and check for. An exception may be needed for
references to fields which have already been initialized.

I think that rule, unfortunately, make it impossible to create circular
structures with the links held in final fields.

On the other hand, this seems like it's getting reasonably far from the
charter of the Java memory model discussion. I guess I should just keep
my mouth shut about ``fixing'' Java in general.

--p
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



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