Inserting In a List

M

markspace

It can be very important in multithreaded context.

But it is not what makes a class immutable.

OK, that's true. The section I linked to refers to such objects as
"thread safe immutable." It's both concepts in one package. Objects
that aren't thread safe aren't immutable, and objects that aren't
immutable aren't thread safe. I guess that's why the two go together.

final is required, but you also have to actually prevent any
modification to the object's state after it is constructed. It is a two
part process, that is true.
 
A

Arne Vajh?j

final is necessary.
No.

It is not sufficient (you also have to not mutate
the object in question after the enclosing object's ctor exits). I'm
pretty sure the field must also be explicitly private. (Implicitly
might not be enough to satisfy what ever escape analysis the Java
compiler does.)


Read Java Concurrency in Practice. That's what I'm referring too.

My copy page 47 footnote 12 says:

"It is technically possible to have an immutable object without all
fields being final"

Is that missing in your copy?

Arne
 
M

markspace

Hmm.

You replied to a post by me and only quoted me.

The first post I made was to Joerg:

"final" makes a variable or field impossible to reassign. It says
absolutely nothing at all about whether or not that variables is
modifiable. What you are thinking of is immutability, something that is not
formalized in Java.


Then you replied to me, saying that the section of the JLS I linked to
"17.5 Final Field Semantics" doesn't define immutability in Java
formally or informally. Which is wrong, if you just scan that section
for uses of the word "immutable." So that's where I kind of lost it.
 
E

Eric Sosman

[...]
I use it a lot, both for that and because accessing stored objects by
key from a TreeMap is almost certainly faster than scanning an ArrayMap
unless it contains very few objects indeed.

Sorry: "ArrayMap"?
I meant ArrayList - my bad.

Okay, I still don't understand: How does "accessing stored
objects by key" pertain to an ArrayList, or to any List? You
can hunt through a List to find an element equal to a search
object (or having some specified relation to it), but "by key?"
There's nothing in the List abstraction to distinguish "key"
from "value" from "haddocks' eyes:" Something's in the List or
it ain't, and that's all.

For my part, I think that if you want to list a directory's
content in some sorted order, the preferred approach is to form
a List of the contents, paying no attention to order, and then
sort it at the end. Spending extra time and memory computing
intermediate results that you won't use seems pointless. YMMV.
 
J

Joerg Meier

OK, that's true. The section I linked to refers to such objects as
"thread safe immutable." It's both concepts in one package. Objects
that aren't thread safe aren't immutable, and objects that aren't
immutable aren't thread safe. I guess that's why the two go together.

I don't have time to answer your other, longer post before I have to leave,
but this one I wanted to interject on before I alt-f4 for the day: while
immutable objects are of course thread safe (due to there not being
anything that can be done to them that needs synchronization), of course
you can make thread safe objects that are mutable.

I don't even know what you were thinking when you wrote that. What do you
think locks and the synchronized keyword are for ? Immutable objects don't
need them.
final is required, but you also have to actually prevent any
modification to the object's state after it is constructed. It is a two
part process, that is true.

Again: you can make immutable objects without final perfectly fine. It is
absolutely not required.

Liebe Gruesse,
Joerg
 
E

Eric Sosman

The first post I made was to Joerg:




Then you replied to me, saying that the section of the JLS I linked to
"17.5 Final Field Semantics" doesn't define immutability in Java
formally or informally. Which is wrong, if you just scan that section
for uses of the word "immutable." So that's where I kind of lost it.

I'm with Arne. The cited section uses the word "immutable"
and "immutability" without defining either. All it says is that
"final" can be an aid to implementing immutable objects -- but it
never says what "immutable" is. It doesn't even say that "final"
confers immutability; on the contrary, it says "final fields must
be *used correctly* [emphasis mine] to provide a guarantee of
immutability."

Toward the end of the section, we're told that String is
"perceived as truly immutable." So now there are two more notions:
"truly immutable" as opposed to merely "immutable," and "perceived
as truly immutable" as opposed to "actually truly immutable, not
dependent on somebody's perception." Where does the JLS define how
these three different kinds of immutability differ? Where does it
*define* even one of them?

Thought experiment: Using the JLS' definition of immutability,
support or refute "java.lang.String is mutable, because it computes
its hashCode() lazily and caches it in a non-final field, thereby
changing the String object's state at the first hashCode() call."

Thought experiment: Using the JLS' definition of immutability,
support or refute "All Java objects are mutable, because all have a
monitor whose state changes every time a synchronized block is
entered or exited. The monitor's state affects the behavior of
all threads attempting to synchronize on the object, so the change
of state is not strictly internal but is visible to all observers."
 
E

Eric Sosman

But now you raise the question, then final is only slightly
involved in immutability in Java.

If is neither sufficient nor necessary to make them
immutable.

final is necessary. [...]

public class Immutable {
private int value;
public Immutable(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}

Claim: Immutable is immutable, despite the lack of "final".
 
L

Lew

markspace said:
final is necessary. It is not sufficient (you also have to not mutate
the object in question after the enclosing object's ctor exits). I'm
pretty sure the field must also be explicitly private. (Implicitly

Nope.

You can have immutable public fields.
might not be enough to satisfy what ever escape analysis the Java
compiler does.)

'final' is essential to the definition of constant variables, which do have special
initialization semantics.

'final' is an essential piece in locking down an immutable reference variable of a type; call
this type 'ImmutableA'.

The object referenced by the member is immutable by dint of its implementation, which
we'll postulate to be correct.

public class ImmutableA
{
private String ident = "Immutable instance";
}

While the object referenced by 'ident' is immutable, this is not enough to make instances
of 'ImmutableA' immutable. For that you must have 'final'.

public class ImmutableA
{
private final String ident = "Immutable instance";
}

Now 'ImmutableA' instances are immutable. Not only that, but in this case, because
'ident' is 'final' and initialized by a constant expression, it is now a constant variable.

So 'final' is most assuredly involved in creating immutability, and is more reliable in the
face of refactoring and other maintenance to preserve it than immutability idioms that
do not use 'final'.
 
M

markspace

My copy page 47 footnote 12 says:

"It is technically possible to have an immutable object without all
fields being final"

Is that missing in your copy?

Right and he goes on to say that String is an example. But String does
rely on final fields -- its char array is final -- and its immutability
derives directly from that. Brain Goetz also adds "don't try this at
home" meaning it's difficult to actually do. He's referring to the
idempotentcy [sic?] of its hash code -- but that doesn't work if the
char array is not final.

I'm just talking about the semantics about final here. I'm trying to
not focus on other implication of having a final field. I think the
subject is complicated enough with out introducing other ways to make an
object thread safe immutable. If you want, I'll agree that there are
exceptions, but I have to insist that final is the normal mechanic, and
if one doesn't understand final fields one won't understand the bits
that Brian Goetz says to "don't try this at home."
 
M

markspace

final is necessary. [...]
public class Immutable {
private int value;
public Immutable(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}

Claim: Immutable is immutable, despite the lack of "final".

Not in the sense of section 17.5 of the JLS, which is what I linked to
above (and also uses the term "thread safe immutable" to describe the
semantics of final fields).

And not in the sense that Brian Goetz uses in JCIP.
 
L

Lew

Eric said:
final is necessary. [...]

public class Immutable {
private int value;
public Immutable(int value) {
this.value = value;
}

public int getValue() {
return value;
}
}

Claim: Immutable is immutable, despite the lack of "final".

'final' can help in some superficially similar scenarios.

public class MutableImmutable extends Immutable
{
private int foo;

public MutableImmutable(int av)
{
super(av);
foo = av;
}

@Override public int getValue()
{
return foo;
}

public void setValue(int av)
{
foo =av;
}
}

Now you can have code like this:

MutableImmutable mui = new MutableImmutable(0);
Immutable immu = mui;
System.out.println("Immutable value = " + immu.getValue());

mui.setValue(-1);
System.out.println("Immutable value = " + immu.getValue());

If the "mui" and "immu" code are in different parts of the application, e.g.., one is
inside a method called separately from the other, you can have mutable behavior
from an 'Immutable' reference even though the parent class is actually immutable.

Furthermore, if 'Immutable#value' were not 'private', then the overriding class can
mutate the behavior of its parent, and break immutability, which is not possible if
the parent class defines 'value' to be 'final'.

So while 'final' is not necessary for immutability, it sure does help.
 
M

markspace

Nope.

You can have immutable public fields.

Well, that's true. I'm clearly getting a little sloppy in my language
with all the different posts I've been making.

A final field can be immutable and public if it's a primitive or if the
object it references is immutable. I think that covers it.
public class ImmutableA
{
private final String ident = "Immutable instance";
}

Now 'ImmutableA' instances are immutable. Not only that, but in this case, because
'ident' is 'final' and initialized by a constant expression, it is now a constant variable.

And because String itself is immutable.

public class NotImmutable {
public final char[] string = {'a','b','c'};
}

final, public, initialized by a constant expression, but not immutable.

This is also immutable:

public class ImmutableB {
public final String string = "abc";
}

Can't change it, so it's OK to be public. Thread safe immutable.

(See my post to Eric, what the JLS actually says in section 17.5 is
"thread safe immutable", which is rather different from just
"immutable." I've been confusing the two terms in my posts when I
really should not. What I've really been talking about I should call
"thread safe immutable" to match the JLS.)
 
A

Arne Vajh?j

My copy page 47 footnote 12 says:

"It is technically possible to have an immutable object without all
fields being final"

Is that missing in your copy?

Right and he goes on to say that String is an example. But String does
rely on final fields -- its char array is final -- and its immutability
derives directly from that. Brain Goetz also adds "don't try this at
home" meaning it's difficult to actually do. He's referring to the
idempotentcy [sic?] of its hash code -- but that doesn't work if the
char array is not final.

I'm just talking about the semantics about final here. I'm trying to
not focus on other implication of having a final field. I think the
subject is complicated enough with out introducing other ways to make an
object thread safe immutable. If you want, I'll agree that there are
exceptions, but I have to insist that final is the normal mechanic, and
if one doesn't understand final fields one won't understand the bits
that Brian Goetz says to "don't try this at home."

"normal mechanic" is not the same as "necessary".

Arne
 
A

Arne Vajh?j

final is necessary. [...]
public class Immutable {
private int value;
public Immutable(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}

Claim: Immutable is immutable, despite the lack of "final".

Not in the sense of section 17.5 of the JLS, which is what I linked to
above (and also uses the term "thread safe immutable" to describe the
semantics of final fields).

The point of final for thread safeness is well known.

But using the distinct term "thread safe immutable" may
be very beneficial here to explain that this is not just
plain immutable.

Arne
 
M

markspace

I'm with Arne. The cited section uses the word "immutable"
and "immutability" without defining either. All it says is that
"final" can be an aid to implementing immutable objects -- but it
never says what "immutable" is.

Well, it does. Section 17.5 has several subsections, and it's defined
in section 17.5.1. I feel one really should read all of 17.5 to
understand final fields however.
It doesn't even say that "final"
confers immutability; on the contrary, it says "final fields must
be *used correctly* [emphasis mine] to provide a guarantee of
immutability."

OK, that might be part of the problem. final is necessary but not
sufficient. I'll concede that, no problem. I misspoke if I implied
otherwise.
Toward the end of the section, we're told that String is
"perceived as truly immutable." So now there are two more notions:
"truly immutable" as opposed to merely "immutable," and "perceived
as truly immutable" as opposed to "actually truly immutable, not
dependent on somebody's perception." Where does the JLS define how
these three different kinds of immutability differ? Where does it
*define* even one of them?

That's a bit of an issue. I think they're just using 'perceived' to
mean visible. There's a happens-before relationship between the end of
the ctor and all other threads in the system. So String is perceived as
immutable by all threads because its fields are visible.

I think immutable is defined in section 17.5.1, with their "hb(w, f),
hb(f, a), mc(a, r1), and dereferences(r1, r2)" stuff. That section is
as I say clear as mud, and I'm relying on Brian Goetz in JCIP to
interpret that mess correctly for me.
Thought experiment: Using the JLS' definition of immutability,
support or refute "java.lang.String is mutable, because it computes
its hashCode() lazily and caches it in a non-final field, thereby
changing the String object's state at the first hashCode() call."

But all threads will see the String's internal char[] to have the same
values, because it's safely published through a final field. So all
threads will calculate the same hash code. This isn't really "thread
safe," except that it is because being idempotent counts. Threads can
never seen any value for the internally stored hash code except 0 or the
correctly computed value.
Thought experiment: Using the JLS' definition of immutability,
support or refute "All Java objects are mutable, because all have a
monitor whose state changes every time a synchronized block is
entered or exited. The monitor's state affects the behavior of
all threads attempting to synchronize on the object, so the change
of state is not strictly internal but is visible to all observers."

Refutation: Only objects with proper final field semantics are immutable
under the JLS's definition. Only those objects are thread safe even
without accessing/invoking their monitor; this latter condition was
specified in that short sentence I quoted at the start of this whole
discussion.

"final fields also allow programmers to implement thread-safe immutable
objects without synchronization."

"Without synchronization" is the whole point of the way Java defines
immutability.
 
M

markspace

The point of final for thread safeness is well known.

But using the distinct term "thread safe immutable" may
be very beneficial here to explain that this is not just
plain immutable.

OK, if that's the issue, then mea culpa. But the JLS and Brian Goetz
use "immutable" to mean "thread safe immutable." Immutable is being
used in a specific, technically defined way, and it's important to keep
that in mind when reading Java literature.

Does the author mean "just regular immutable" or "thread safe
immutable?" With Java, often it's going to be the latter, and I do mean
in the sense of the JLS when I use immutable to refer to final field
semantics.
 
L

Lew

And because String itself is immutable.

I said "and initialized by a constant expression", which is a stronger assertion than immutability.

It encompasses immutability, so the fact that String is immutable is covered by my comment.
public class NotImmutable {
public final char[] string = {'a','b','c'};
}

final, public, initialized by a constant expression, but not immutable.

It is *not* initialized by a constant expression!

I should have given the full term, a "compile-time constant expression" (JLS ?15.28):
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28
"A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following: [list of restricted syntax] ..."

The restricted syntax allows only certain expressions involving primitives or 'String's.

An array is neither primitive nor a 'String'.
This is also immutable:

public class ImmutableB {
public final String string = "abc";
}

'string' is also a constant variable.
Can't change it, so it's OK to be public. Thread safe immutable.

Furthermore, it's a constant variable, so its visibility is different that it would be without 'final'.
Also, simply referencing a static constant variable does not invoke initialization of its containing class.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1
(See my post to Eric, what the JLS actually says in section 17.5 is
"thread safe immutable [sic]", which is rather different from just
"immutable." I've been confusing the two terms in my posts when I
really should not. What I've really been talking about I should call
"thread safe immutable" to match the JLS.)

All "thread-safe immutable" means is immutable and not seen by another thread until after the
immutability is assured by a memory barrier.
 
L

Lew

markspace said:
Well, it does. Section 17.5 has several subsections, and it's defined
in section 17.5.1. I feel one really should read all of 17.5 to
understand final fields however.

Section 17.5.1 never mentions the word "immutable" at all.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.1

Section 17.5, however, does define "thread-safe immutable":
" A thread-safe immutable object is seen as immutable by all threads, even if a data race is used to pass references to the immutable object between threads."

The word "immutable" is apparently to be understood in its common computer-science meaning.

[snip]
I think immutable is defined in section 17.5.1, with their "hb(w, f),
hb(f, a), mc(a, r1), and dereferences(r1, r2)" stuff. That section is
as I say clear as mud, and I'm relying on Brian Goetz in JCIP to
interpret that mess correctly for me.

That section does not address immutability, but finality.

It says that the value of a reference will not be seen to change if the conditions pertain,
but says nothing about the state of the object referenced.

There isn't one.

Clearly they use "immutable" to refer to observable ("perceived") state.

Any two calls to a fully-constructed 'String' instance's 'hashCode()' will be perceived
to have the same value, and thus is immutable to conventional observation.
But all threads will see the String's internal char[] to have the same
values, because it's safely published through a final field. So all
threads will calculate the same hash code. This isn't really "thread
safe," except that it is because being idempotent counts. Threads can

Yes, it is really thread safe, assuming you wait for the ctor to complete.
never seen any value for the internally stored hash code except 0 or the
correctly computed value.

And if you follow the rules of thread-safe immutability, and I don't know how you would
dodge them for 'String', threads will never see 0.
 
M

markspace

I should have given the full term, a "compile-time constant
expression" (JLS ?15.28):
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28

"A compile-time constant expression is an expression denoting a
value of primitive type or a String that does not complete abruptly
and is composed using only the following: [list of restricted
syntax] ..."

Ah OK, a term a wasn't familiar with. Thanks for the info.
Furthermore, it's a constant variable, so its visibility is different
that it would be without 'final'. Also, simply referencing a static
constant variable does not invoke initialization of its containing
class.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1

I think I get this. Constant variables can be initialized at compile
time, and so so their visibility is compile time and later. An access
to a constant variable wouldn't cause a class to initialize, whereas an
access to my public final char[] would cause the whole class to initialize.
All "thread-safe immutable" means is immutable and not seen by
another thread until after the immutability is assured by a memory
barrier.

Yes, but I think it's causing confusion, as Arne and possibly Joerg are
assuming that immutable means something more like the plain English
meaning of that word, and they're not taking into account the special
meaning applied by the JLS. I had to modify my terminology to be more
clear.
 
M

markspace

Section 17.5.1 never mentions the word "immutable" at all.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.1

Huh, so it doesn't. OK, it just defines the semantics of final fields then.
Section 17.5, however, does define "thread-safe immutable": ....
The word "immutable" is apparently to be understood in its common
computer-science meaning.

Section 17.5 says this in its second paragraph:

"final fields must be used correctly to provide a guarantee of
immutability."

That's the last sentence. To me that's ascribing special semantics to
just the word 'immutable.' If it's saying "final fields must be used"
then it's special for final fields. I realize there a qualifier on
that, but the qualifier is "correctly" and they're just pointing out
it's a little tricky. final fields must be used is the key point.
(Used incorrectly, of course, they won't guarantee immutability.)

I see how you might read that differently, but without final fields the
number of useful immutable classes is pretty small. (I'm ignoring
stateless objects here.)
And if you follow the rules of thread-safe immutability, and I don't
know how you would dodge them for 'String', threads will never see
0.

??? The first thread to calculate a hash code will always see 0.
That's what triggers the hash code calculation, rather than just
returning the value stored in the hash code field.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top