From: markspace on
Lew wrote:
> Lew wrote:
>>> stooges = Collections.unmodifiableSet( sts );
>
> markspace wrote:
>> Part of my point was that a line like this is 100% unneeded. The JLS
>> considers "stooges" to be unmodifiable just based on the fact that it is
>> never modified.
>
> Until someone modifies the class later by, for example, adding method
> 'public Set <String> getStooges()'.
>
> Could you cite the particular part of the JLS to which you refer here,
> please?


Apparently it's in there, but I can't find it right now. I'm relying
mainly here on JCIP, which gives nearly the same example as I did (sans
the method that makes the class not thread safe) and states that the
class is immutable and thread safe. See p 47.

Much later, Brian Goetz explains why this class is immutable. He
describes initialization safety in section 16.3, p 349, and states
states that for objects _properly constructed_, not only will all
threads see any final variables correctly, but also any objects
_reached_ through such a final field. Then he again gives an example
similar to the Stooges one and states that the class is immutable and
thread safe.

Hopefully that'll help you. I'm going to review the JLS some more
myself and see if I can pin down which sections guarantee this behavior.

From: markspace on
John B. Matthews wrote:
> In article <i27k65$lse$1(a)news.eternal-september.org>,
> markspace <nospam(a)nowhere.com> wrote:
>
>> (*) Is there an actually name for "lazily-immutable?" I seem to
>> remember it being talked about in JCIP but I can't find a reference
>> now.
>
> Is this what you mean? "A blank final is a final variable whose
> declaration lacks an initializer."


No not that. The kind of lazy thread safety where an idempotent value
is calculated and stored with out any synchronization, like String's
hashcode.

From: markspace on
markspace wrote:

> Apparently it's in there, but I can't find it right now.


Ah here I think it is. In section 17.5, the fourth paragraph. Actually
all four of those beginning paragraphs are important, but the fourth one
specifically says that final fields are special in a constructor:


"...when the object [being constructed] is seen by another thread, that
thread will always see the correctly constructed version of that
object's final fields. It will also see versions of any object or array
referenced by those final fields that are at least as up-to-date as the
final fields are."

<http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.5>


Which means that final fields and the objects those fields reference are
thread safe and immutable after a constructor completes, as long as
those objects aren't later modified. According to JCIP.
From: Andreas Leitgeb on
markspace <nospam(a)nowhere.com> wrote:
> Thus, if you have your own class which follows the rules for immutablity
> for some of its fields, those fields will also be treated as immutable &
> safe for publication with a data race.

> public class Stooges {
> private final List<String> stooges; private int count;
> public Stooges { stooges = new ArrayList<String>();
> stooges.add("Lary"); stooges.add("Curly"); stooges.add("Moe");
> }
> public boolean isStooge(String name) {return stooges.contains(name);}
> public int size() {
> if( count == 0 ) { count = stooges.size(); } return count;
> }
> }
> The field "stooges" is immutable and treated as such by the JVM.

I find it irritating to use the word "immutable" for a final field.
Not that it was wrong, but for fields there is already the adjective
"final" that says it all. Immutability is a "feature" of some classes'
instances, and depends on a couple of design-decisions.

If you had a non-private accessor (just a getter) for field stooges,
then your size()-implementation would be incorrect despite the final'ity
of stooges. A user could then use the reference to add another element
to the list and "final" wouldn't prevent that.

> The fact that "count" is kind of lazily-immutable (*) still is
> thread safe;
Huh?
As stooges is private and has not even got a getter, your class would
still be immutable even without the "final" keyword.

I don't know, how the compiler or jvm are even aware of practical
immutability, and what consequences it would draw from it, even if
it really "knew".

> Hmmm, I wonder if a class can have no final fields, have at least one
> mutable private field and still be immutable.
Well, yes: if it assigns all fields only in the constructor, and nowhere
else and none of the fields is other than private.

From: markspace on
Andreas Leitgeb wrote:

> I find it irritating to use the word "immutable" for a final field.


Yeah, sloppy terminology by me. I should have said instances of the
class are immutable.


> If you had a non-private accessor (just a getter) for field stooges,
> then your size()-implementation would be incorrect despite the final'ity
> of stooges. A user could then use the reference to add another element
> to the list and "final" wouldn't prevent that.


Yes, and some documentation would help a maintenance programmer. Even
though "learn Java" is a suitable answer, I still think documentation
plays a large role in communicating the design and implementation to
other programmers. Marking immutable as such should be part of the
documentation. Making some sort of coded phrase or annotation for a
project, so that all types of objects which are immutable due to final
fields and initialization safety are marked the same way would also be a
good idea, a bit like Brian Goetz's thread safety annotations.


> As stooges is private and has not even got a getter, your class would
> still be immutable even without the "final" keyword.

This bit I don't think is true. I'm pretty sure the JLS only guarantees
visibility of these fields due to the presences of the final keyword.
See the Final Fields section of the JLS, section 17.5 iirc.

And by "guarantees visibility" I mean in all circumstances, including
publication using a data race. It's that case, the data race, where I
think a non-final field would fail. (If you'll excuse my alliteration.)