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.
Related
I am reading about the specific guidelines that needs to be followed while creating Immutable Class in Effective Java.
I read that In Immutable class method should not allowed to be overridden otherwise overridden method may change the behaviour of method. Following are the design approaches available in java to solve this problem :-
We can mark class final but as per my understanding, it has a one disadvantage that it makes the class inextensible.
Secondly is to make individual methods final but I can not get other disadvantage besides that we need to individually mark each method as final in order to prevent overridding.
As per book,better approach is to make the constructor private or package-private and provide public static factory method for creating object.
My question is: Even if we include private or default constructor in the class, it cannot be extended anymore in same package (in other package in case of package-private constructor), it has a same problem which the first one had. How is it considered as the better approach than the previous ones?
An immutable object should not be extensible. Why?
Because extending it will allow either direct access to fields (if they are protected which would allow writing methods that change them), or adding state which may be mutable.
Imagine we wrote a class FlexiblyRoundableDouble that extends Double, which has an additional field roundingMode that lets us choose a "rounding mode". You could write a setter for this field, and now your object is mutable.
You can argue that if all the methods are set as final, you cannot change the original behavior of the object. The only methods that could access your roundingMode field are new methods that are not polymorphically available if you assign your object to a Double variable. But when a class's contract says that it's immutable, you make decisions based on that. For example, if you write a clone() method or copy constructor for a class that has Double fields, you know that you don't need to deep-copy the Double fields, as they do not change their state, and can therefore be safely shared between the two clones.
Also, you can write methods that return the internal object without fearing that the caller will then change that object. If the object was mutable, you'd have to make a "defensive copy" of it. But if it's immutable, it's safe to return a reference to the actual internal object.
However, what happens if someone assigned a FlexiblyRoundableDouble to one of your Double fields? That object would be mutable. The clone() would assume it isn't, it will be shared between two objects, perhaps even returned by a method. The caller would then be able to cast it back as a FlexiblyRoundableDouble, change the field... and it will affect other objects that use that same instance.
Therefore, immutable objects should be final.
All this has nothing to do with the constructor issue. Objects can be safely immutable with public constructors (as demonstrated by String, Double, Integer and other standard Java immutables). The static factory method is simply a way utilizing the fact that the object is immutable, and several other objects can hold references to it safely, to create fewer objects with the same value.
Providing a static factory method gives you room to implement the Flyweight Pattern.
They're stating that you should hide the possibility of creating a new object using a constructor, and should rather make a call to a method which checks if an object with similar state exists in the "object pool" (a map filled with objects waiting to be re-used). Not re-using immutable objects is a waste of memory; this is why String literals are encouraged, and new String() is shunned (unless needed).
class ImmutableType {
private static final Map<Definition, ImmutableType> POOL = new HashMap<>();
private final Definition definition;
private ImmutableType(Definition def) {
definition = def;
}
public static ImmutableType get(Definition def) {
if(POOL.contains(def))
return POOL.get(def);
else {
ImmutableType obj = new ImmutableType(def);
POOL.put(def, obj);
return obj;
}
}
}
Definition stores the state of the ImmutableType. If a type with the same definition already exists in the pool, then re-use it. Otherwise, create it, add it to the pool then return it as the value.
As for the statement about marking the class final, immutable types should not be extensible in the first place (to avoid possibly modifying behavior). Marking every method final is just crazy for immutable classes.
I would appreciate help in understanding the following from 'Java Concurrency in Practice':
Calling an overrideable instance method(one that is neither
private nor final) from the constructor can also allow the
this reference to escape.
Does 'escape' here simply mean that we may probably be calling an instance method,before the instance is fully constructed?
I do not see 'this' escaping the scope of the instance in any other way.
How does 'final' prevent this from happening?Is there some aspect of 'final' in instance creation that I am missing?
It means calling code outside the class, and passing this.
That code will assume that the instance is fully initialized, and may break if it isn't.
Similarly, your class might assume that some methods will only be called after the instance is fully initialized, but the external code is likely to break those assumptions.
final methods cannot be overridden, so you can trust them to not pass this around.
If you call any non-final method in the constructor for a non-final class, a derived class might override that method and pass this anywhere.
Even when you call final methods, you still need to make sure that they are safely written – that they do not pass this anywhere, and that themselves don't call any non-final methods.
"Escape" means that a reference to the partially-constructed this object might be passed to some other object in the system. Consider this scenario:
public Foo {
public Foo() {
setup();
}
protected void setup() {
// do stuff
}
}
public Bar extends Foo implements SomeListener {
#Override protected void setup() {
otherObject.addListener(this);
}
}
The problem is that the new Bar object is being registered with otherObject before its construction is completed. Now if otherObject starts calling methods on barObject, fields might not have been initialized, or barObject might otherwise be in an inconsistent state. A reference to the barObject (this to itself) has "escaped" into the rest of the system before it's ready.
Instead, if the setup() method is final on Foo, the Bar class can't put code in there that will make the object visible before the Foo constructor finishes.
I believe the example is something like
public class Foo {
public Foo() {
doSomething();
}
public void doSomething() {
System.out.println("do something acceptable");
}
}
public class Bar extends Foo {
public void doSomething() {
System.out.println("yolo");
Zoom zoom = new Zoom(this); // at this point 'this' might not be fully initialized
}
}
Because the super constructor is always called first (either implicitly or explicitly), the doSomething will always get called for a child class. Because the above method is neither final nor private, you can override it in a child class and do whatever you want, which may conflict with what Foo#doSomething() was meant to do.
Per secure coding
Example BAD code:
final class Publisher {
public static volatile Publisher published;
int num;
Publisher(int number) {
published = this;
// Initialization
this.num = number;
// ...
}
}
If an object's initialization (and consequently, its construction) depends on a security check within the constructor, the security check can be bypassed when an untrusted caller obtains the partially initialized instance. See rule OBJ11-J. Be wary of letting constructors throw exceptions for more information.
final class Publisher {
public static Publisher published;
int num;
Publisher(int number) {
// Initialization
this.num = number;
// ...
published = this;
}
}
Because the field is nonvolatile and nonfinal, the statements within
the constructor can be reordered by the compiler in such a way that
the this reference is published before the initialization statements
have executed.
Correct code:
final class Publisher {
static volatile Publisher published;
int num;
Publisher(int number) {
// Initialization
this.num = number;
// ...
published = this;
}
}
The this reference is said to have escaped when it is made available
beyond its current scope. Following are common ways by which the this
reference can escape:
Returning this from a non-private, overridable method that is invoked from the constructor of a class whose object is being
constructed. (For more information, see rule MET05-J. Ensure that
constructors do not call overridable methods.)
Returning this from a nonprivate method of a mutable class, which allows the caller to manipulate the object's state indirectly. This
commonly occurs in method-chaining implementations; see rule VNA04-J.
Ensure that calls to chained methods are atomic for more information.
Passing this as an argument to an alien method invoked from the constructor of a class whose object is being constructed.
Using inner classes. An inner class implicitly holds a reference to the instance of its outer class unless the inner class is declared
static.
Publishing by assigning this to a public static variable from the constructor of a class whose object is being constructed.
Throwing an exception from a constructor. Doing so may cause code to be vulnerable to a finalizer attack; see rule OBJ11-J. Be wary of
letting constructors throw exceptions for more information.
Passing internal object state to an alien method. This enables the method to retrieve the this reference of the internal member object.
This rule describes the potential consequences of allowing the this
reference to escape during object construction, including race
conditions and improper initialization. For example, declaring a field
final ordinarily ensures that all threads see the field in a fully
initialized state; however, allowing the this reference to escape
during object construction can expose the field to other threads in an
uninitialized or partially initialized state. Rule TSM03-J. Do not
publish partially initialized objects, which describes the guarantees
provided by various mechanisms for safe publication, relies on
conformance to this rule. Consequently, programs must not allow the
this reference to escape during object construction.
In general, it is important to detect cases in which the this
reference can leak out beyond the scope of the current context. In
particular, public variables and methods should be carefully
scrutinized.
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.
Common design practice is to make instance variables private and have public getters and setters to access them. But many times I have seen code samples on the internet that have constructors that assign values directly to the private instance variable instead of using the setters inside constructors. Am I missing something?
public class Person{
private String name;
public Person(String name){
//is this right, seems like the whole encapsulation purpose is defeated
this.name = name;
//shouldn't this be used
setName(name);
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
}
You are not missing anything. What you do depends entirely on your situation. However, consider this:
It is very common to do parameter validation in a setter. For example, let's say I have a class with field that can hold a value 0 through 10 (the "throws" is unnecessary for the exception type below but I include it for clarity):
public class Example {
private int value;
public Example () {
}
public final int getValue () {
return value;
}
public final void setValue (int value) throws IllegalArgumentException {
if (value < 0 || value > 10)
throw new IllegalArgumentException("Value is out of range.");
}
}
Here, setValue() validates 'value' to make sure it sticks to the rules. We have an invariant that states "an Example will not exist with an out of range value". Now let's say we want to make a constructor that takes a value. You might do this:
public class Example {
...
public Example (int value) {
this.value = value;
}
...
}
As you can see, there is a problem. The statement new Example(11) would succeed, and now an Example exists that breaks our rules. However, if we use the setter in the constructor, we can conveniently add all parameter validation to the constructor as well:
public class Example {
...
public Example (int value) throws IllegalArgumentException {
setValue(value); // throws if out of range
}
...
}
So there are many benefits to this.
Now, there are still cases when you might want to assign values directly. For one, maybe you don't have setters available (although I would argue that creating private or package private setters is still desirable, for the reasons mentioned above, for reflection/bean support if necessary, and for ease of validation in more complex code).
Another reason might be that perhaps you have a constructor that knows, somehow, ahead of time that valid values will be assigned, and therefore doesn't need validation and can assign variables directly. This is usually not a compelling reason to skip using setters though.
However, all-in-all, it's generally a good idea to use the setters everywhere when possible, it will usually lead to cleaner and clearer code that is easier to maintain as complexity increases.
Most of the examples you see where people set variables directly are just people being "lazy" - which is perfectly acceptable if the situation warrants it (perhaps you're writing a quick test program or application and don't want to implement a bunch of setters, for example). There's nothing wrong with that as long as you keep the big picture in mind and only be "lazy" when it's appropriate.
Something I'd like to add based on some of the other answers here: If you override a setter in a subclass, and the data you are setting breaks invariants that the base class assumes, then either the relevant setters should be made final or the base class should not make those assumptions. If overriding setters breaks base class invariants then there is a bigger issue at hand.
You'll notice the getter/setter is final in the above example. This is because our rule is that "any Example must have a value from 0 to 10". This rule therefore extends to subclasses. If we did not have that rule and if an Example could take on any value, then we would not need a final setter and could allow subclasses to override.
Hope that helps.
Sometimes when you would want make the class immutable, it is just one of the things you need to do. And don't have setter methods at all in that case.
Depending on the context, the use of getters and setters is actually a bigger violation of encapsulation than using member variables in constructors. If you want to set the member variable 'name' of this class, either of these approaches would work since the construction is hidden from the caller and thus not violating encapsulation. One warning is that the use of setName within the constructor might call an overrided method in a subclass which may not be what you want (since it may leave name undefined in the superclass).
Here's a similar question to yours that may provide additional insight:
calling setters from a constructor
the private variables are accessible directly anywhere in the class
settng variabels private is to encapsulate them from other classes
Setting variables to private is to encourage encapsulation from other classes.
Unless setName(String) was meant to do something extra (which the method name doesn't imply), it's unnecessary to use the setter while you're in the class where the private variable is.
This does not defeat encapsulation since the private member is still hidden from the other classes
If the modifier method does not contain any logic and just sets the member then there is no difference between directly setting the member of calling its setter method although for better practice the setter should be called.
The setter indicates that this person's name might change in the future and allows it easily without creating an entire person object again.
Initializing variables inside constructor is a very common practice. It can be used to assign values to variables based on which constructor user has called. You cannot write code based on assumption that the client code will invoke setter method to assign value to instance variables. It is always safe to assign default value to a variable when its object is created (i.e inside constructor).
There is a difference between initializing variables within constructor and setting it to different value as per requirement of the calling code(using setter method). Both have different purposes and different objectives.
This is perfectly normal. Some variables might need to be initialized as soon as the object is created, hence it makes sense to pass them in the constructor and many times we may not want to provide setters for those variables to avoid changing the values after object is created.
Its ok to directly assign values with in class provided setter doesn't do any other processing.
Basically setters/getters are used to provide restrictive access to private data such as returning copy of the data instead of reference of private object, validating data in getter etc..
Since the constructor is part of the object itself, and we are sure what we are doing is right, then its ok.
My preferred approach (as described by Joshua Bloch in "Effective Java") is to make the constructor private, make the fields final (i.e., eliminate the setters entirely), and require clients to obtain instances either using the Builder Pattern or Factory Method Pattern, which would take care of any necessary validation to protect invariants. Then the (private) constructor would simply directly assign the given parameters (which have already been validated by the Builder or Factory Method) to the appropriate fields, which are private and final.
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.