Prev: Immediate Start: Need Designer's (Visual/Graphic),Beverly Hills,California,
Next: a question about alias of reference
From: markspace on 22 Jul 2010 00:41 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 22 Jul 2010 00:43 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 22 Jul 2010 01:10 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 22 Jul 2010 09:04 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 22 Jul 2010 12:55
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.) |