I was recently asked this quesion. But was not able to explain concisely what exactly sets both these concepts apart.
For example
Final and Immutable:<
final String name = "John";
When you write the above your code is telling the compiler that the reference name
will always point to the same memory location. Now why I say memory location because it might happen that the object the reference is pointing to is mutable like array or list of integers. So if I say final int[] arr = {5,6,1};
I can do arr[2] = 3;
but I can't do arr = {3,4,5}
cause you will be trying to assign a new int[]
to final variable arr
which is a new memory location and seeing this compiler will show error.
String name = "John";
name = "Sam";
Above the name
variable of type String
is immutable because String
in java is immutable
which means you can't change the state of the object pointed out by the reference name
once it is created and even if you change it to Sam
it is now a different object which is pointed by the reference name
and the previous object John
will have no reference and can be collected by garbage collector whenever it runs if it has no other references pointing to it.
Immutable means that once the constructor for an object has completed execution that instance can't be altered.
This is useful as it means you can pass references to the object around, without worrying that someone else is going to change its contents. Especially when dealing with concurrency, there are no locking issues with objects that never change
e.g.
class Foo
{
private final String myvar;
public Foo(final String initialValue)
{
this.myvar = initialValue;
}
public String getValue()
{
return this.myvar;
}
}
Foo doesn't have to worry that the caller to getValue() might change the text in the string.
If you imagine a similar class to Foo, but with a StringBuilder rather than a String as a member, you can see that a caller to getValue() would be able to alter the StringBuilder attribute of a Foo instance.
final is a reserved keyword in Java to restrict the user and it can be applied to member variables, methods, class and local variables. Final variables are often declared with the static keyword in Java and are treated as constants. For example:
public static final String hello = "Hello"; When we use the final keyword with a variable declaration, the value stored inside that variable cannot be changed latter.
For example:
public class ClassDemo {
private final int var1 = 3;
public ClassDemo() {
...
}
}
Note: A class declared as final cannot be extended or inherited (i.e, there cannot be a subclass of the super class). It is also good to note that methods declared as final cannot be overridden by subclasses.
Benefits of using the final keyword are addressed in this thread
The object cannot be changed.
final String s = "Hello";
// Not allowed.
s = "Bye";
The contents of the object cannot be changed.
BigInteger one = BigInteger.ONE;
// Does not change `one` or `BigInteger.ONE`.
one.add(BigInteger.ONE);
// Have to do it this way.
BigInteger two = one.add(one);
final
ensure that the address of the object remains the same. Where as the Immutable
suggests that we can't change the state of the object once created.
final
is just a keyword whereas Immutable
is a pattern.
In Case of your first question you have marked the variable as
final
, which means you would not be able to change the memory address of it and can't assign a value once more.In case of your second question
Immutable
ensures you can't change the state of the object you have created.
Immutable : String and wrapper classes are immutable. Because of the String constant pool they can't change their value inside an object, but they can change references of object holding different values.
String s1 = new String("cant't change");
Final : when we create a reference of String
Final String s2 = "cant't change";
The reference for s2
is pointing to object which has value " can't change" inside it.
The reference s will now always point to the object holding value "can't change". It's reference can't be changed.
final
means that you can't change the object's reference to point to another reference or another object, but you can still mutate its state (using setter methods e.g). Where immutable means that the object's actual value can't be changed, but you can change its reference to another one.
Concerning the second part of your question (immutability part), the compiler creates a new String
object with the value of "Sam", and points the name
reference to it.