Java: Final field freeze on object reachable from final fields - java

DZone refcard titled "Core Java Concurrency" states:
Once set, final field values
cannot be changed. Marking an object reference field as final does
not prevent objects referenced from that field from changing later. For
example, a final ArrayList field cannot be changed to a different
ArrayList, but objects may be added or removed on the list instance.
and
Final field freeze includes not just the final fields in the object but also all
objects reachable from those final fields.
I am not entirely clear about the second statement. Does this mean that if I have a final field in class A of type Class B, which in turn have a final field of type Integer, then final field freeze for an instance of class A completes only after the final field freeze for b.c have already happened?
public class A{
public final B b = new B();
}
public class B{
public final Integer c = 10;
}

Does this mean that if I have a final
field in class A of type Class B,
which in turn have a final field of
type Integer, then final field freeze
for an instance of class A completes
only after the final field freeze for
b.c have already happened?
I think I would carefully say that final field freeze in this case means that when you create an instance of A and safely publish it, other objects will never see an uninitialized value for b or c.
I would also say that when you are creating the instance of B inside A, other initialization code inside A will never see an uninitialized value for c.
One case where I have encountered real questions around final field freeze is for example a class that contains a (mutable) HashMap, intended only for read, initialized during construction:
public class DaysOfWeek {
private final Map daysOfWeek = new HashMap();
public DaysOfWeek() {
// prepopulate my map
daysOfWeek.put(0, "Sunday");
daysOfWeek.put(1, "Monday");
// etc
}
public String getDayName(int dayOfWeek) {
return daysOfWeek(dayOfWeek);
}
}
The question arises here: assuming this object is safely published, and given that there is no synchronization here, is it safe for other threads to call getDayName()? The answer is yes, because final field freeze guarantees that the HashMap and everything reachable from it (here it's just strings, but could be arbitrarily complex objects) is frozen at the end of construction. [If you want to actually modify this map after construction, then you'll need explicit synchronization around reads and writes.] Here's a lengthier blog exploring the topic and check the comments for some interesting responses by people like Brian Goetz.
btw I'm the author of the refcard

Java Concurrency in Practice mentions this in section 16.3:
Initialization safety guarantees that
for properly constructed objects,
all threads will see the correct
values of final fields that were set
by the constructor, regardless of how
the object is published. Further, any
variables that can be reached
through a final field of a properly
constructed object (such as the
elements of a final array or the
contents of a HashMap referenced by a
final field) are also guaranteed to be
visible to other threads. For objects
with final fields, initialization
safety prohibits reordering any part
of construction with the initial load
of a reference to that object. All
writes to final fields made by the
constructor, as well as to any
variables reachable through those
fields, become “frozen” when the
constructor completes, and any thread
that obtains a reference to that
object is guaranteed to see a value
that is at least as up to date as the
frozen value. Writes that initialize
variables reachable through final
fields are not reordered with
operations following the
post-construction freeze.

Right. That follows from JMM
Look for paragraph:
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
Since constructor will not be finished until class B initializes that guarantee freeze of B.c

The guarantee is stronger than you appear to think. The final field semantics apply even to mutable objects that are assigned to final fields (with the usual restrictions). SO extending your example to make A.b private and B mutable (but not externally mutable).
public class A {
private final B b = new B();
public Integer get() { return b.c; }
}
public class B {
public Integer c = 10;
}
In this case, A.get will never return null even under unsafe publication. Of course this example is completely abstract and therefore meaningless. Typically it is important for arrays (for instance in String) and collections.

It does not really make sense to talk about what becomes final before what else. To your program, once your object is created (actually from the moment the field is assigned once) the reference can not change anymore.
Since the B instance is created before the A instance, you could say c becomes final before b, but it does not really matter.
Where the order is important is when you have multiple final fields in a single class. If you want to use the value of one final field in the assignment of another, you should only access fields that already have been initialized.
To be honest, that 'final field freeze' sentence does not make much sense to me.

Related

Should initialized final fields that are immutable always be made static?

I was wondering if there would ever be a legitimate use case for non-blank/initialized immutable final fields.
In other words:
class Foo {
private final String bar = "bar";
}
Versus
class Foo {
private static final String BAR = "bar";
}
Answer, as in most cases is: it depends.
What does it mean to make it static? Effectively it means to let all instances use same value of that field.
Most of the time immutable object could be shared among all instances without problems. Like in this case it makes sense to make it static since you want all instances of your class to use same value of that field.
But lets not forget that even if object is immutable it still has mutable property like monitor which is used in synchronization mechanisms. Lets say your class have
private final Object lock = new Object();
and each instance is supposed to use its own lock object for synchronization (like synchronize(lock){...}). Despite the fact that Object is immutable, making lock static is not what we want (value of lock should not be shared, but separate for each instance).

Does improperly constructed object only affect visibility for the thread it publishes inside of tbe constructor?

When http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight says
The values for an object's final fields are set in its constructor. Assuming the object is constructed "correctly", once an object is constructed, the values assigned to the final fields in the constructor will be visible to all other threads without synchronization. In addition, the visible values for any other object or array referenced by those final fields will be at least as up-to-date as the final fields.
What does it mean for an object to be properly constructed? It simply means that no reference to the object being constructed is allowed to "escape" during construction.
Does it mean that only the thread that had seen an improperly constructed object might see it in a bad state but all other threads are fine?
For example say you have some simple code
public class Foo {
final int x = 5;
public Foo() {
new Thread(() -> System.out.print(x)).start();
}
}
Does that mean that only that thread that had seen the implicit this reference might have visibility issues, but any other threads to come that use the instance of Foo is guaranteed to see a perfectly visible Foo reference and its field x to be 5?
The JLS states,
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
There's no indication that the visibility guarantee toward one thread would be affected by unsafe publication with respect to another thread.

Does self-reference in the constructor counts as "escaping"?

Reading this article about JSR-133, it says:
all of the writes to final fields (and to variables reachable
indirectly through those final fields) become "frozen," ...
If an object's reference is not allowed to escape during construction,
then once a constructor has completed and a thread publishes a
reference to an object, that object's final fields are guaranteed to
be visible ...
The one caveat with initialization safety is that the object's
reference must not "escape" its constructor -- the constructor should
not publish, directly or indirectly, a reference to the object being
constructed.
My question is about what is considered escaping. More specifically, I want to know if this (somewhat artificial and strange) code results in a safely-publishable Child object:
class Parent {
/** NOT final. */
private int answer;
public int getAnswer() {
return answer;
}
public void setAnswer(final int _answer) {
answer = _answer;
}
}
public class Child extends Parent {
private final Object self;
public Child() {
super.setAnswer(42);
self = this;
}
#Override
public void setAnswer(final int _answer) {
throw new UnsupportedOperationException();
}
}
Firstly, while Parent is clearly mutable, Child is "effectively immutable", since the parent setter that would allow mutability is not reachable anymore.
The reference to "this" in the constructor is not visible to anyone (not getter, and not passed to any other object). So, does this count as "escaping"?
But the object as a whole is being referenced by a final field (self), and so in theory, it's whole content should then be "frozen". OTOH, the final field is itself not reachable, so maybe it doesn't count; I could very well imagine the JIT just completely optimizing it away.
If "self" was made accessible through a getter, but the getter is not called in the constructor, does it then count as escaping (assuming it didn't before)? This would prevent the JIT from optimizing it away, so that it must then "count", maybe?
So, is Child "safely-publishable", and if not, why, and would a getter for "self" change the answer?
In case the purpose of the question isn't clear, I think that if this works, it would allow one to easily make a mutable class "safely-publishable", by just extending it as shown above.
You may be misunderstanding the meaning of escaping. The point is that the value of this must not reach any code foreign to the constructor. I think a few examples would explain it better:
setting a private field to this doesn't count as escaping;
calling a private method, which in turn doesn't call any further methods, and doesn't assign this to a foreign object's variable, doesn't count as escaping;
calling a public, overridable method belonging to this does count as escaping unless the class is final. Therefore your code lets this escape when you call setAnswer, not when you assign this to self. Why? Because a subclass may override this method and publish this to any foreign code.
A note on your reasoning about self: self is reachable from this and this doesn't depend on the fact that a foreign caller cannot get its value. It is enough that a method may internally dereference it. Anyway, the rules about freezing do not take into account the access level of variables. For example, everything is reachable via reflection.

why fields should be final in immutable class?

Strategy for defining immutable class says that
all the fields should be final.
For ex:
private String name;
Why does it have to be final?
Since I am not giving setter methods for it? It can't be changed.
Thanks.
If you read
private final String name;
you know the field is immutable.
If you read
private String name;
you have to read the entire class to check it is not changed anywhere. This is means much more work for you.
You may remember now, having just written the class that you didn't add a setter, but after writing many more classes you read your own class six month later, you won't remember reliably.
Even if it is not changed now, someone (possibly yourself) could change it later by adding code. However, you might have made the assumption the value won't change.
In short, only make it non-final when you mean the value to change, and make it final when you didn't expect it to change. Don't leave it as a may be/may be not.
Now imagine you are used to being clear about which fields can be changed and which cannot. This saves you a lot of work when reading some else's code. But you discover that you are reading code which is not clear and non-final doesn't mean it was changed, it now means you have to check things, you wouldn't normally have to check which is one more headache in trying to understand some code you really don't need.
A simple example of how much harder it is to read code to determine if a field is effectively final.
public class A {
static class B {
private int x;
}
// some code
This all looks fine up to this point, no setters or even methods in B. So B.x is immutable right?
static class C {
public void update(B b, int x) {
b.x = x; // this really compiles
}
}
}
Oops no, you have to read the whole class file.
It is far better for you to make every field you can final (which should have been the default IMHO) when you write the code, rather than leaving it for someone to figure out later.
The main reason (IMHO) is that when field is final is guaranteed to be visible in other threads immediately after constructor is finished.
Keeping the field final emphasizes the fact that it cannot be changed anywhere else.
Self documenting code the the field should not be changed
Compiler will help you by giving error if you change the field somewhere else
So final helps in many ways for making object Immutable.
It's good practice to make immutable fields final, even on otherwise mutable objects.
Note that private fields of one object in fact CAN be accessed by other instances of the same class.
An object (class or instance) is immutable, if its internal state cannot be changed (reflection doesn't count).
Making a field final guarantees only that the value (if it's a primitive) or reference (for non-primitives) cannot be changed.
For non-primitives, this doesn't automatically mean that the referenced value is also immutable. Which means that if your final field references, for example, a list, one cannot exchange the list, but add/remove values from it, thus changing the state of the object.
For an object to be immutable:
The internal state must be determined upon construction and can never change
This means all fields that define the state must be final (you may have other helper fields which don't belong to the state, that's ok but rare).
This also means that all refernced objects must be immutable. Some objects such as String are already immutable, others such as collections can be wrapped to make them immutable (Collections.immutableList|Set|Collection|...)
Making primitive types final ensures immutability. However making non primitive objects final sometimes makes no sense since final object states can be mutated.As Greg points out this depends on the type of Object in question
As the example you showed, all properties are primitive hence final keword make sense.
One benifit of declaring a field final is that it allows compiler to detect attempts to change the field during refactoring. A class can be immutable even if its fields are not final.
JVM guarantees that final fields of a class will be initialized before any thread gets hold of the object. Without this guarantee, a reference to an object may be published, i.e. become visible, to another thread before all the fields of this object are initialized, due to reorderings or other optimizations. This could cause racy access to these fields.
This is why, when creating an immutable object, you should always make all its fields final, even if they are not accessible via getter methods.

Java Code Static Final variable usage

I've got two classes below. Both have one variable 'reply' with a getter. There is no setter method for this variable. Only difference is in ClassOne, the variable is static final.
So whats the difference and which one is preferred?
public class ClassOne {
private static final String reply = "Success";
..
public String getReply() {
return reply;
}
// no setter
}
and Class 2
public class ClassTwo {
private String reply = "Success";
..
public String getReply() {
return reply;
}
// no setter
}
UPDATE 1:
What I want to know is that when there is no setter for a variable, should the variable be declared as static final for optimization? or does it not matter?
should the variable be declared as static final for optimization?
final certainly, not only for optimization but for clarity and because it can make your object immutable, which is always a good thing to have.
static completely changes the nature of the field and has nothing to do with the existence of setters: do you want only one instance of that field, or do you need one per instance of your class?
Non static example: a Person has a name, which is a constant (for a given person = per instance), so you can use a non static final field, which you only set once when creating a new Person:
private final String name;
Static example: Whenever you don't have a name for a Person, you want to use a default value - that is a global constant which is shared among all persons that don't have a name and you can use a static final field:
private static final String NO_NAME = "John Doe";
When you set the variable as final, you are telling everybody (the compiler, the runtime) that it cannot be changed. This can help a lot with optimizations like inlining all of the occurrences of the variable with its value.
When you have a constant string which can not be changed, you should make it a static final string.
Static means that less memory is needed for instance of the class, because the instances don't need individual copies.
Final allows some optimizations and thus makes your program faster.
There are few things good to know:
final variables can be checked by compiler that they are not accidentally changed.
references to non-static variables are contained in instance so there is small needless memory consumption in addition
static variables are shared across all instances of the same class, so you can be sure that all instances work with the same value
final static variables, especially the Strings are linked in compilation time so they need not to be dereferenced at runtime from the field. Due to that it cannot be changed even by the reflection, because such field is not used at runtime.
Setting the reference to final ensures you can't change the reference. Note however that if the object referred to is mutable then you could still change that (not in this instance, since Strings are immutable).
I normally make fields final and initialise them in the constructor. By favouring immutability my classes are easier to debug and are more likely to be safe in threaded environments. It's easier to remove the immutability constraint than add it.
I also do this for method arguments. Rarely (ever) do I want to change a method argument, and making them final will catch inadvertent assignments.
I try not to use static except for final constants. Unless it's something like a logger, I don't really want one instance per class, and (of course) this doesn't work in the case of multiple classloaders. It's also getting close to the singleton anti-pattern, and this impacts on easy testing and (potentially) threading.
The fact that you make the variable static means that a single instance of that variable will be shared among all the instances of ClassOne, as the variable is bound to the class itself, not to its instances. Apart from any JVM optimisations, you'll have a single instance of reply for every instance of ClassTwo.
First one is Constant you need to know value of it at compile time.
private static final String reply = "Success";
second is just simple member variable. So any case first one is preferred since second one will create value for each object.
Assuming that you intended **private final String reply** in second case
A final variable can only be initialized once, either via an initializer or an assignment statement. It does not need to be initialized at the point of declaration: this is called a "blank final" variable.
In second case you can also declare and initialize it in constructor
private final String reply;
You can read more about it here

Categories