Prev: Immediate Start: Need Designer's (Visual/Graphic),Beverly Hills,California,
Next: a question about alias of reference
From: markspace on 21 Jul 2010 16:09 Lew wrote: > The field in question is private, and does not change the externally > observable state. So the String instance acts like it's immutable, but > has mutable internal state. > > So in a real sense String is mutable, and just as real, it's immutable. To expound on this a bit, final fields in a constructor are treated specially by the JVM and JLS. Even if an entire class is not strictly immutable, the values and objects referred to by final fields will be treated as immutable by the compiler & runtime. 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. The fact that "count" is kind of lazily-immutable (*) still is thread safe; this whole class can be treated as immutable, not as effectively immutable, with no repercussions or harm done. (*) 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. Hmmm, I wonder if a class can have no final fields, have at least one mutable private field and still be immutable.
From: Lew on 21 Jul 2010 18:25 On Jul 21, 4:09 pm, markspace <nos...(a)nowhere.com> wrote: > Lew wrote: > > The field in question is private, and does not change the externally > > observable state. So the String instance acts like it's immutable, but > > has mutable internal state. > > > So in a real sense String is mutable, and just as real, it's immutable. > > To expound on this a bit, final fields in a constructor are treated > specially by the JVM and JLS. Even if an entire class is not strictly > immutable, the values and objects referred to by final fields will be > treated as immutable by the compiler & runtime. > > 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. The > fact that "count" is kind of lazily-immutable (*) still is thread safe; > this whole class can be treated as immutable, not as effectively > immutable, with no repercussions or harm done. > Still, it's better most times to make something like 'count' final. The reason 'hash' wasn't final in 'String' was the ubiquity of 'String' measured against its likely usage, making the possible speedup likely to be worthwhile. Nearly no custom classes will have the dynamic to justify lazy-loading for the attributes one considers loading lazily. public class Stooges { private final Set <String> stooges; private final int count; public Stooges { HashSet <String> sts = new HashSet <String> (); sts.add( "Lary" ); sts.add( "Curie" ); sts.add( "Moo" ); stooges = Collections.unmodifiableSet( sts ); count = stooges.size(); } public boolean isStooge( String name ) { return stooges.contains( name ); } public int size() { return count; } } -- Lew
From: markspace on 21 Jul 2010 19:14 Lew wrote: > Still, it's better most times to make something like 'count' final. Righto. My use of count was just an example, not best practice. > stooges = Collections.unmodifiableSet( sts ); 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.
From: Lew on 21 Jul 2010 20:35 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? -- Lew
From: John B. Matthews on 21 Jul 2010 20:39
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." <http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.12.4> -- John B. Matthews trashgod at gmail dot com <http://sites.google.com/site/drjohnbmatthews> |