Recently I attended an interview.
I was asked how you can make a class Immutable.
I told him the answer.
But then he asked me why the fields are final?
I answered so that the user doesn't accidentally change the value of the field and it will give compiler error if he does so.
Now he ask me there is a immutable class with only getter methods.
Then in this class what is the use of final?
I was not able to answer. He told there is a reason behind that.
Can somebody explain?
From Effective Java:
Make all fields final. This clearly expresses your intent in a manner that is enforced by the system. Also, it is necessary to ensure correct behavior if a reference to a newly created instance is passed from one thread to another without synchronization, as spelled out in the memory model.
Now he ask me there is a immutable class with only getter methods.
Then in this class what is the use of final?
Only getter methods do not ensure that a class is immutable. If you expose the internal state than a client can change the class's state.
Immutable means that you can not change an objects state once it is created.
Making all fields final and providing only getters will not make it immutable out of the box. Imagine the following code:
public class MyString {
private final char[] content;
public MyString(String str){
this.content = str.toCharArray();
}
public char[] getContent(){
return this.content; // internal state exposed. You should return a copy.
}
}
This class has only final fields and only getter methods but is still mutable. Imagine this client code:
MyString myString = new MyString("test");
myString.getContent()[0] = 'f';
Now he ask me there is a immutable class with only getter methods.
Then in this class what is the use of final?
The use of final is to express your intention with java's language features and therefore enforce them by the compiler.
So making a variable final is good for primitive types, but you must take care if the variable is a reference. In this case you must either ensure that
the object you are referencing is also immutable or
only your instance has access to that object.
The later can only be ensured by the programmer. So take extra care when you return references.
Well, immutability is of course achieved in the way that an object is used, rather than by enforcement. You could always change a final field's value with Reflection.
The use of it is to allow the compiler to prevent you from breaking immutability, as well as to denote the need for immutability (such as when you use an inner class that uses a method-local reference).
'final' as the keyword's name suggest means that the attribute to which final keyword is attached can't be changed(in terms of value) in other words it behaves like a constant.if fields are not 'final' then inside local method you can change the value of fields.
Related
I know the prerequisites for a class to be made immutable. I looked into the code, there were no setters for any variable defined in String. For StringBuffer and StringBuilder, there were two setters:
setLength which called the same named setters of parent AbstractStringBuilder.
setCharAt which manipulated the char value[] of parent AbstractStringBuilder.
String is "immutable" because its API (the public methods it defines) provides no way for a caller to change its state. Other classes, like StringBuilder, are mutable because they do provide "mutators", or methods that change the state of the class.
Under the covers there's nothing different between mutable or immutable objects. An object is just the primitive and reference values that make up its fields, and all fields are conceptually mutable (ignoring the final keyword for the moment). But by restricting the visibility of these fields (e.g. making them private) and defining methods that limit what a caller can do (like defining a getter but not a setter) you can provide a guarantee that instances of the class will be immutable, which is to say you promise none of its fields (or the objects they reference) will change over its lifetime.
By using the final keyword you can be even more explicit that a class is immutable. If you simply don't provide mutator methods, it's still possible for a class to be mutable if some private method mutates the class. If all the fields in a class are marked final, that's not (normally) possible. You can be confident any class with only final primitive (or immutable) fields is immutable*. That isn't the only way to guarantee immutability, but it is the clearest - any attempt to mutate the class would be a compiler error.
* The class itself also has to be declared final, otherwise someone could potentially create a mutable subclass. But again, there are other ways to ensure immutability. Using final everywhere is just the easiest to see.
There are a lot of things here.
All fields are private.
There are no setters / mutators.
Construction injection of arguments (using which String has to be constructed).
Reference to underlying char array (char[] value) does not leak out of this class.
Mutability is not merely defined by the presence or absence of setter/mutator methods.
In the case of StringBuilder and StringBuffer, there's a plethora of other methods (e.g. all the append() methods) that alter the internal state of the object, and hence make it mutable.
The string class is immutable and one of reasons behind that is the class is declared as final though there are other reasons also.
But why is StringBuffer or StringBuilder final and still they are mutable?
So what other factors are deciding for String to be immutable?
StringBuffer and StringBuilder are mainly used for string concatenating operations within a single method, the code using them often being generating by the compiler. So being extended is not the typical use case.
On the other hand, being final allows better optimizations within a JVM, at least in the past; today’s HotSpot JVM does not require it, however, there never was a reason to change the final declaration from these classes.
Note that extending StringBuilder and overriding methods for polymorphic behavior would be a bit pointless as there is no public method within the entire JRE accepting or returning StringBuilder instance (besides within StringBuilder itself). There are Appendable and CharSequence filling this gap and offering much more flexibility.
The concepts of mutability and immutability are entirely different from the concept of final classes. They simply depend on what kind of methods or operations a class provides. String has no methods that allow modifying its contents while StringBuffer and StringBuilder have such methods. Declaring an immutable class final just helps prohibiting subclasses which could introduce methods supporting mutation, but that’s not a hard requirement.
Why String is final and immutable are actually two, partially independent, questions.
First, String is part of the java.lang package, as the name suggests the types in this package are related to implement the java language to its definition.
Thats one reason it is final, if I take a String anywhere I can rely on it to behave as the java language defined a String behaves (because you can't create your own subclass that has different behavior).
Second, the immutability of String is "just" a design choice, but it has favorable implications in that again when you pass a String somewhere (e.g. as a File name), the API called can be sure you can't change the string and directly store references to it (as opposed to as make a copy of it if it were mutable). It also significantly simplifies working with String in multithreaded environments.
So why is StringBuilder/Buffer final? This is again "just" a design choice, but there aren't any as strong and obvious justifications behind it as there are for String. They just did it that way.
String is not immutable because it is final; final and immutability are more or less orthogonal. Making a class final is part of one approach to making a class immutable, but making a class final is also part of a good programming practice in general no matter what behavior you want for the class.
An immutable class must not be extensible by outside users. It may have several implementations inside its own package, like e.g. Guava's ImmutableMap, in which case the class need not be final, but you can also forbid extension by e.g. making constructors package-private so users outside the package cannot extend the class.
A final class is any class that cannot be extended. This is recommended practice in many cases in Effective Java -- that is, whenever you don't have an explicit reason to make the class subclassable, making it final is generally good practice.
I think you are having a misconception about "final" keyword when used with class.
When a variable is declared final it's value can't change once they are initialized.
i.e.
final int i=5;
i++// Will give an error.
But:
In case of classes:
Final keyword servers the purpose of making the class non-inheritable i.e. that class can't be sub-classed!.
i.e.
final class question
{}
class answer extends question//Will give an error!!!
{}
Answer to your question:
Now, you are right that string is immutable because once a string object is initialized it can't be changed and Stringbuilder and Stringbuffer are mutable(Vice - Versa), and this has got nothing to do with these classes being final!
You aren't subclassing them right!
I hope I helped!
Edit:
I think I should explain this completely that how Stringbuilder is mutable and String is not:
I'll explain this code by code:
Stringbuilder a = new Stringbuilder("a");//Initial String!!
a.append("b"); //Now the String is ab!!
So, since the same object i.e. a got its value changed it is known as mutable.(An object i.e. capable of changing its value after being initialized).
Now String:
String a = "a";
a = a + "b"; //Explained below.
Though to you this may appear that string object a is changing its value and hence is mutable but it's not, as behind the scenes Stringbuilder is working.
i.e.
the actual thing did by compiler in the above code is:
a = new StringBuilder(a.append("b")); //The actual code...
So, now the variable a stores the values "ab".
I know this is confusing, but if you read my code precisely you will see that the object a never changed it's values it just got assigned a new value!!
This is what is known as being immutable i.e. an object cant change after being initialized!
I hope I helped
So what other factors are deciding for String to be immutable?
The answer is simple as all the data member of String class is final which makes it as immutable.
If you want to make your own class immutable, make all the data members of that class as final. And initialise all the final data members in constructor so that once they have initialise, never changed.
If you will see String class implementation for immutability, you will find:
private final char[] value;
And initialisation of value will be in constructor part:
public String(String toCopy){
value = toCopy.value;
}
And if you will see StringBuffer class implementation, you will find:
private char[] value;
public StringBuffer(String toCopy){
value = toCopy.value;
}
So, in above code you can see, the String class's value data member will be once initialise and will never change but the StringBuffer class's value data member can be initialise and change many times.
So this makes String class immutable not making a class final.
If you concern is around extending the behavior of StringBuilder or StringBuffer you can still do it - just not by inheritance. You can you composition or delegation. Classes String, StringBuffer, StringBuilder all implement CharacterSequence. So create you class implementing CharacterSequence and delegate all methods to the composed StringBuffer or StringBuilder. Composition over Inheritance is the golden rule in GoF - see this discussion too.
Making a class final is an additional and more potent layer of encapsulation - maybe the author of the code does not feel anyone should be modifying the behavior by extension since s/he may feel a subclass of the class in question may not be truly representative of itself (in terms of conversion).
StringBuffer was the concept of mutable String, that is thread-safe, that is, all operations performed on it are synchronized.
StringBuilder is recommended replacement for StringBuffer. It was introduced, when it came out, that synchronization is not used very often, when it comes to Strings.
String is just String. Why is it immutable? Perhaps the reason was thread-safety and cost of such. What if you want to store global String, that is read only? If it was mutable, then all reads must have been synchronized - an additional overhead, that is not necessary here.
That's why these three classes were provided - you chose what do you want to pay for.
As you noted, all these classes - String, StringBuilder and StringBuffer are final. The reason is that you can't (and shouldn't) modify behaviour of these classes.
It is better to implement another class, that contains (for example) StringBuilder and provide similar functionality, than extend it.
If you want, you may provide similar functionality by implementing CharSequence - all these classes implement this interface.
What is the benefit of making fields private while creating an immutable class?
I have seen why while creating immutable class, fields are declared as private? but I didn't get understand anything from this post.
Can anybody please explain me the same?
The best way to explain is with an example:
public class Immutable {
private final char[] state = "Hi Mom".getChars();
public char[] getState() {
return state.clone();
}
}
Here we have a properly encapsulated, immutable class. Nothing can change the state (modulo nasty reflective tricks).
Now lets JUST change the access on the field:
public class Immutable {
public final char[] state = "Hi Mom".getChars();
public char[] getState() {
return state.clone();
}
}
Note we are still making the defensive copy in getState ... as before ... but now someone can do this:
Immutable mu = new Immutable();
mu.state[1] = 'o';
... and our supposedly immutable object's state has changed.
That is ONE reason why it is a good idea to keep the fields private. (Obviously, this only applies to field whose types are mutable reference types.)
A SECOND reason is encapsulation. Declaring fields as private hides implementation details, which reduces the risk of unwanted cross-coupling. If I don't do this, then I (or some other programmer) might be tempted to write code that depends on the internals of Immutable. That is going to lead to problems if I need to change them; e.g. changing the type of state to String. Problems as in "lots more code to check / change".
A THIRD reason is that non-private (and particularly public) fields can be an impediment to subclassing. If I declare a field as public then, the I can't undeclare it in a subclass. If I want to hide the field or modify the behavior of the field in a subclass (by overriding) ... I can't. By contrast, if the field is private and access is via instance methods, I can override those methods in subclasses. Or I can choose to not use the field at all.
The only reason for making final fields private is binary compatibility, and this actually holds true irrespective of whether the containing class is immutable or not.
A class C is said to offer binary compatibility to classes X and Y
that use class C if class C can be refactored without having to
recompile classes X and Y.
You only need to worry about binary compatibility if you are developing a library to be used by software that is written by others and therefore you have no control over. If you are in this situation, then you pretty much have to use full encapsulation, which means that you have to make all fields private and only access them via getters.
However, in the vast majority of cases, what we are developing is top-layer, self-contained application software, not libraries to be used by others. So, in the vast majority of cases, there is no good reason to make final fields of immutable classes private, it is just a widely held misconception. In a top-layer, self-contained application scenario you can always refactor everything and your IDE will accordingly refactor all references, so immutable classes do not need encapsulation.
Some of the answers suggest that if a field is not private, and it points to a mutable object, then someone might go and modify that mutable object, which is of course correct, but then we go into the philosophical question of what really is an immutable object. Can an object still be called immutable if it contains mutable objects? Is the mutability of an object dependent on the mutability of objects that it contains?
My rule is as follows:
There are two kinds of fields: contained and referenced, which can otherwise be thought of as owned and unowned. As an example, think of an Employee class: the name of the employee is contained/owned by the class, since each employee has their very own name. However, the Employee class may also contain a reference to a Department class, and of course each employee does not have their very own department, so the department is a referenced/unowned field.
A contained/owned field like Employee.name must of course be final and immutable in order for the owning class (Employee) to be immutable. Such a field does not need to be private, unless we are aiming for binary compatibility.
A referenced/unowned field like Employee.department also needs to be final if the referring class (Employee) is to be immutable, but it does not have to be immutable, and its immutability does not affect the immutability of the referring class. Even in this case, (and unless we are aiming at binary compatibility,) a referenced/unowned field generally does not need to be private, because there is still no issue of encapsulation: we are not going to be making a defensive copy of an employee department, that would be nonsensical.
So, unless we are aiming for binary compatibility, then both in the case of contained/owned immutable fields and referenced/unowned fields (which can be either mutable or immutable,) the fields can stay public final and everything will be fine.
final class A{
final List l = new ArrayList();
}
Suppose you have list, and you made this list as final it's reference not modified at all.
But this list is easily accessible to outer classes and they are easily modify it's contents.
so prevent that we have to add private access specifier.
An object that is referred to by a public final reference-type field can still be modified through that field. (What you can't do is change the field to refer to a different object.)
To disallow unwanted modifications, you need to make the field private.
public fields can be accessed from any class anywhere and modified. But making fields private and final and using constructor injection / defensive copies, you ensure that the class is completely immutable.
Non-private fields may still be read-accessed - and if that field is an object, mutable operations on that object may be invoked.
Making the fields private will prevent this possibility.
If you'll use public field other objects will be able to change state of your "almost-immutable" object which will break encapsulation and make it a mutable object.
I have doubt a doubt regarding making an immutable class.
As per the java docs.
I made the class final( no one can extend)
field are private.
no setter function.
If fields are mutable then send a cloned copy of the field.
My doubt is that its compulsory to make a field of my class as final?
If there are no setter methods (and presumably no other methods to affect the fields' values) and the fields themselves are private, marking them as final is somewhat redundant.
Having said that - its a good defensive practice which many projects' standards follow.
Although as many say its not mandatory to mark the fields as final I would say atleast in one case that I can think of you need to mark the fields as final and that is in the case if you want to make your immutable class thread safe.
According to Java memory model:-
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.
JLS final thread safety
So if you have an immutable class with instance variables which you initialize in constructor as non final variables then there is no guarantee of thread safety as the writes to the non final variables may not be visible to other threads even though the constructor has fully run ( Note recreating this is very difficult as this may occur in a highly concurrent application)
Immutable = not changeable. So making properties final is a good idea. If not all properties of an object are protected from being changed I wouldn't say the object is immutable.
BUT an object is also immutable if it doesn't provide any setters for it's private properties.
An immutable object will never change, but anything that it refers to might change.
Deep immutability is much stronger: neither the base object nor any object you can navigate to from it will change.
Could you please clarify that why final keyword is required before class when we are making it an immutable one.
I mean, if we declare all of it's attributes as private and final, then also it is an immutable class, isn't it?
Sorry if the question seems easy, but i am truly confused about it. Help me out.
Editted:
I know that a class declared final can't be subclassed.. But if each attribute is private and final then what difference does that make?
As stacker says, final makes sure the class isn't subclassed. That's important so that any code which is relying on its immutability can do so safely.
For example, immutable types (where each field is also of an immutable type) can be freely used between threads without worrying about data races etc. Now consider:
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
That looks like you can share Person instances freely across threads with no problem. But what about when the object you're sharing is actually a mutable subclass:
public class Employee extends Person {
private String company;
public Employee(String name, String company) {
super(name);
this.company = company;
}
public void setCompany(String company) {
this.company = company;
}
public String getCompany() {
return company;
}
}
Now instances of Employee aren't safe to share between threads, because they're not immutable. But the code doing the sharing may only know about them as instances of Person... leading them into a false sense of security.
The same goes for caching - it should be safe to cache and reuse immutable types, right? Well, it is safe to cache instances which are genuinely of an immutable type - but if you're dealing with a type which itself doesn't allow mutation, but does allow subclasses, it's suddenly not safe any more.
Think about java.lang.Object. It doesn't have any mutable fields, but it's clearly a bad idea to treat every Object reference as if it's a reference to an immutable type. Basically it depends on whether you think about immutability as a property of the type or of objects. A truly immutable type declares "any time you see a reference of this type, you can treat it as immutable" - whereas a type which allows arbitrary subclassing can't make that claim.
As an aside, there's a half-way house: if you can limit the subclassing to only "trusted" places, you can ensure that everything's immutable, but still allow that subclassing. The access in Java makes that tricky, but in C# for example you could have a public class which only allowed subclassing within the same assembly - giving a public API which is nice and strong in terms of immutability, while still allowing for the benefits of polymorphism.
A class that is declared final cannot be subclassed. See also http://docs.oracle.com/javase/tutorial/java/IandI/final.html
The different semantics of all uses of the final keyword are described in the The Java Language Specification
4.12.4 final Variables Page 80
8.1.1.2 final Classes Page 184
8.3.1.2 final Fields Page 209
8.4.3.3 final Methods Page 223
You don't strictly need final to make an immutable class. i.e. you can make an immutable class without it being final.
However, if you don't make it final, then it is possible for someone to extend a class and create a subclass that is mutable (either by adding new mutable fields, or overriding methods in a way that enables you to mutate protected fields of the original immutable class). This is a potential problem - it violates the Liskov Substitution Principle, in the sense that you would expect the property of immutablity to be preserved by all subtypes.
Hence, it is usually good practice to make immutable classes final to avoid this risk.
'final' as the keyword's name suggest means that the attribute to which final keyword is attached can't be changed(in terms of value) in other words it behaves like a constant.
As per your question if all members of the class is made private and final but the class is not made final then the same class can be inherited but the super class member are immutable as final keyword is attached to them.
An immutable object is an object which state is guaranteed to stay identical over its entire lifetime. While it is perfectly possible to implement immutability without final, its use makes that purpose explicit, to the human (the software developer) and the machine (the compiler).
Immutable objects carry some very desirable characteristics:
they are simple to understand and easy to use
they are inherently thread-safe: they require no synchronization
they make great building blocks for other objects
Clearly final is going to help us define immutable objects. First in labelling our object as immutable, which makes it simple to use and understand by other programmers. Second in guaranteeing that the object's state never changes, which enable the thread-safe property: thread concurrency issues are relevant when one thread can change data while another thread is reading the same data. Because an immutable object never changes its data, synchronizing access to it is not needed.
Create an immutable class by meeting all of the following conditions:
Declare all fields private final.
Set all fields in the constructor.
Don't provide any methods that modify the state of the object; provide only getter methods (no setters).
Declare the class final, so that no methods may be overridden.
Ensure exclusive access to any mutable components, e.g. by returning copies.
A class declared final cannot be sub classed. Other classes cannot extend final class. It provides some benefit to security and thread safety.
If all public and protected methods are final and none of them allows modifying private fields, and all public and protected fields are both final and immutable, then I guess it could be said class is semi-immutable, or sort of constant.
But things break down when you create a subclass and need to override equals and hashcode. And can not because you made them final... So the whole thing is broken, so just make the whole class final to prevent programmer from being a fool by accident.
As an alternative to doing this kind of bastardized version immutability, you have several options.
If you want to attach extra data to immutable instance, use Map. Like if you wanted to add age to name, you would not do class NameAge extends String... :-)
If you want to add methods, create a class of static utility functions. That is a bit klunky, but it is the current Java way, Apache commons for example is full of such classes.
If you want to add extra methods and data, create a wrapper class with delegate methods to methods of the immutable class. Anybody needing to use the extra methods needs to be aware of them anyway, and there is not much practical difference in casting to derived non-immutable class or doing something like new MyWrapper(myImmutableObj) for many use cases.
When you really have to have reference to original imutable object (like storing it in existing class you can not change), but need the extra data somewhere, you need to use the Map approach to keep the extra data around, or something like that.
If an immutable class Foo is sealed ("final"), then anyone who receives a reference to a Foo may be assured that if Foo was implemented correctly, the referenced instance will in fact be immutable. If an immutable class is not sealed, then someone who receives a reference to a Foo may be assured that if the actual class of of the referenced object (which may be Foo or some derivative type implemented by some arbitrary unknown person) was implemented correctly, the instance will be immutable. Leaving Foo unsealed means that anyone who relies upon Foo to be immutable will have to trust that everyone who writes a class that derives from Foo will implement it correctly. If one wants to be certain that every reference to a Foo will in fact target an immutable instance without having to rely upon the authors of derivative classes to abide by the contract, making Foo final can aid in such assurance.
On the other hand, the possibility that a class might derive from Foo but violate its immutability isn't terribly different from the possibility that a class which derives from any other class might violate the contracts of its parent class. Any code which accepts a reference of any type which can be subclasssed by outside code might be given an instance of a subclass which violates its parent's contract.
The fundamental question when deciding whether an immutable class should be sealed is the same as for any other class: whether the benefits of leaving the type unsealed outweigh any dangers that would be posed by doing so. In some cases, it may make sense to have an extensible immutable class, or even an abstract class or interface whose concrete implementations are all contractually obligated to be immutable; for example, a drawing package might have an ImmutableShape class with some concrete fields, properties, and methods to define 2D transformations, but an abstract Draw method, allowing for the definition of derivative types ImmutablePolygon, ImmutableTextObject, ImmutableBezierCurve, etc. If someone implements an ImmutableGradientFilledEllipse class but fails to have that type make its own copy of a mutable GradientColorSelector, the colors of gradient-filled polygons might change unexpectedly, but that would be a fault of the ImmutableGradientFilledEllipse class, and not the consuming code. Despite the possibility of a broken implementation failing to uphold the "immutability" contract, an extensible ImmutableShape class would be much more versatile than a sealed one.