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.
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.
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.
I'd like to create a few immutable objects for my codebase. What's the best way to really deliver the message that a given class is intended to be immutable? Should I make all of my fields final, and initialize during object construction? (This seems really awkward...) Should I create some Immutable interface, and have objects implement it? (Since Java doesn't have some standard interface behind this, I thought they had some other way of dealing with it.) What's the standard way this is dealt with? (If it's simply done by adding a bunch of comments around the fields exclaiming that they shouldn't be modified once initialized, that's fine too.)
Should I make all of my fields final, and initialize during object construction?
Yes. And ensure that those types are themselves immutable, or that you create copies when you return values from getter methods. And make the class itself final. (Otherwise your class on its own may be immutable, but that doesn't mean that any instance of your class would be immutable - because it could be an instance of a mutable subclass.)
(This seems really awkward...)
It's hard to know what to suggest without knowing how you find it to be awkward - but the builder pattern can often be useful. I usually use a nested static class for that, often with a static factory method. So you end up with:
Foo foo = Foo.newBuilder()
.setName("asd")
.setPoints(10)
.setOtherThings("whatever")
.build();
Yes and no. Making all fields final is not a guarantee in and of itself. If you'd like to get really in-depth with this there are a number of chapters in Effective Java by Joshua Bloch dealing with immutability and the considerations involved. Item 15 in Effective Java covers the bulk of it and references the other items in question.
He offers these five steps:
Don’t provide any methods that modify the object’s state (known as muta-
tors).
Ensure that the class can’t be extended.
Make all fields final.
Make all fields private.
Ensure exclusive access to any mutable components.
One way to learn how to do all of this is to see how the language designers make classes immutable by reviewing the source for classes like String which are immutable (for example see http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java).
Write a unit test that will fail if your coworkers make the class mutable.
Using Mutability Detector, you can write a test like this:
import static org.mutabilitydetector.unittesting.MutabilityAssert.assertImmutable;
#Test public void isImmutable() {
assertImmutable(MyImmutableThing.class)
}
If a coworker comes along, and, for example, adds a setter method to your class, the test will fail. Your use case is one of the core purposes of Mutability Detector.
Disclaimer: I wrote it.
I was asked this question in an interview recently:
Can you name any class in the Java API that is final that shouldn't be or one that isn't and should be'?
I couldn't think of any. The question implies that I should know all the API classes like the back of my hand, which I personally wouldn't expect any Java developer to know.
If anyone knows any such classes, please provide examples.
java.awt.Dimension isn't final or immutable and should have been. Anything that returns a Dimension (e.g a Window object) needs to make defensive copies to prevent callers from doing nasty things.
The first examples that come to mind are some of the non-final Number subclasses, such as BigDecimal and BigInteger, which should probably have been final.
In particular, all of their methods can be overriden. That enables you to create a broken BigDecimal, for example:
public class BrokenBigDecimal extends BigDecimal {
public BigDecimal add(BigDecimal augend) {
return BigDecimal.ZERO;
}
}
That could create significant issues if you receive BigDecimal from an untrusted code for example.
To paraphrase Effective Java:
Design and document for inheritance or else prohibit it
Classes should be immutable unless there's a very good reason to make them mutable
In my opinion, your reply should have been that it is a matter of taste which classes should be final and which shouldn't.
There are good reasons to make Integer, Double and String all final.
There are good reasons to complain about this.
Then there is BitSet, BitInteger etc. which could be made final.
There are a number of situations where classes are not final, but they also cannot be extended reasonably, so they probably should have been made final.
To pick on a particular class: BitSet. It is not final, yet you cannot extend it to add a bit shift operation. They might as well have made it final then, or allow us to add such functionality.
The Date class leaps out. It is a mutable simple value class (essentially a wrapper around a long), but a good heuristic is that simple value classes should be immutable. Note also its numerous deprecated methods: more evidence that the design was botched. The mutability of the Date is a source of bugs, requiring disciplined defensive copying.
one that isn't and should be
Most final classes in java are designed so due w/ security considerations in mind, overall there are relatively few final ones. For instance java.util.String is final for that very reason. So are many others.
Some classes w/ private c-tor are declared final (Math, StrictMath) but it doesn't matter in such a case.
Basically unless there are security issues involved I don't care if the class is final, yet you can always use non-public c-tor w/ some factory, effectively limiting the ability to subclass. Usually that's my preferred way as it allows package-private subclassing.
In short: I can't think of a final class that should not be, however there are some that could potentially have been. For instance java.lang.Thread being final might have not needed to protect vs malicious clone().
I believe java.util.Arrays and java.util.Collections should be declared final.
Here is why:
They contain only static members and a private constructor.
The private constructor prevents those classes from being extended.
So, those classes cannot be extended, but this fact is not visible in their public interface. Declaring them final would expose it and clarify intent.
Additionally, java.lang.Math (another so-called utility class) has the same structure and it is also declared final.
Check the String class which is final and probably should had been your answer in the interview.
Check the docs.
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
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.