38

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";

if I now write

name = "Sam";

I will get a compiler error

Immutable:

String name = "John";
name = "Sam"; 

it works.

I think this explains a part of it in application. But can I get a good, easy to understand explanation on both these topic?

nanospeck
  • 3,388
  • 3
  • 36
  • 45
  • 1
    I can´t flag this question for some reason, duplicate of [This](http://stackoverflow.com/questions/16061030/must-all-properties-of-an-immutable-object-be-final) – Mayuso Dec 04 '15 at 11:53
  • 3
    @Mayuso IMHO both questions are far un-related please don't flag duplicate. I got the perfect answers here. – nanospeck Dec 05 '15 at 05:26

9 Answers9

64

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.

Mohammed Aouf Zouag
  • 17,042
  • 4
  • 41
  • 67
20

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.

Community
  • 1
  • 1
Vivek Singh
  • 2,047
  • 11
  • 24
6

When you have a field declared as final, the reference will not change. It will always point at the same Object.

if the Object is not immutable, the methods on it can be used to change the Object itself - it is the same Object, but its properties have been changed.

Ankur Singhal
  • 26,012
  • 16
  • 82
  • 116
6

Immutable: http://www.programcreek.com/2009/02/diagram-to-show-java-strings-immutability/

when you change the String, create new String object ('abcdef') and change the reference from 'abce' to 'abcdef'.But you can not remove 'abcd'. Only change the reference. That is immutable.

final:

Actually final is a keyword.When you add it to variable, you can not change the reference.

Damith Ganegoda
  • 4,100
  • 6
  • 37
  • 46
4

final

The object cannot be changed.

final String s = "Hello";
// Not allowed.
s = "Bye";

immutable

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);
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
2

When you use keyword "final", that means that you cannot change the reference of the object that the variable points to. So, in this case variable "name" cannot be made to point to another string object. However, please note that we can change the contents of the object since we are using a final reference. Also Strings in java are inherently immutable. i.e. you cannot change its contents. So, in your case, final will make a final reference to a string object. and since you can't change the variable to point to another string object, code fails.

See the code below to understand working of final variable.

public class test {

public static void main(String[] args) {
    final A aObject = new A();
    System.out.println("Old value :" + aObject.a);
    aObject.a = 2;
    System.out.println("New value :" + aObject.a);
}} 

class A {
public int a = 1;}
achin
  • 169
  • 8
2
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.

Yug Singh
  • 3,112
  • 5
  • 27
  • 52
1

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

Community
  • 1
  • 1
Haseeb Anser
  • 494
  • 1
  • 5
  • 19
0

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.

UserF40
  • 3,533
  • 2
  • 23
  • 34