In Java we use final
keyword with variables to specify its values are not to be changed.
But I see that you can change the value in the constructor / methods of the class. Again, if the variable is static
then it is a compilation error.
Here is the code:
import java.util.ArrayList;
import java.util.List;
class Test {
private final List foo;
public Test()
{
foo = new ArrayList();
foo.add("foo"); // Modification-1
}
public static void main(String[] args)
{
Test t = new Test();
t.foo.add("bar"); // Modification-2
System.out.println("print - " + t.foo);
}
}
Above code works fine and no errors.
Now change the variable as static
:
private static final List foo;
Now it is a compilation error. How does this final
really work?
Best Answer
This is a favorite interview question. With this questions, the interviewer tries to find out how well you understand the behavior of objects with respect to constructors, methods, class variables (static variables) and instance variables.
In the above case, we have defined a constructor for 'Test' and gave it a 'setFoo' method.
About constructor: Constructor can be invoked only one time per object creation by using the
new
keyword. You cannot invoke constructor multiple times, because constructor are not designed to do so.About method: A method can be invoked as many times as you want (Even never) and the compiler knows it.
Scenario 1
foo
is an instance variable. When we createTest
class object then the instance variablefoo
, will be copied inside the object ofTest
class. If we assignfoo
inside the constructor, then the compiler knows that the constructor will be invoked only once, so there is no problem assigning it inside the constructor.If we assign
foo
inside a method, the compiler knows that a method can be called multiple times, which means the value will have to be changed multiple times, which is not allowed for afinal
variable. So the compiler decides constructor is good choice! You can assign a value to a final variable only one time.Scenario 2
foo
is now a static variable. When we create an instance ofTest
class,foo
will not be copied to the object becausefoo
is static. Nowfoo
is not an independent property of each object. This is a property ofTest
class. Butfoo
can be seen by multiple objects and if every object which is created by using thenew
keyword which will ultimately invoke theTest
constructor which changes the value at the time of multiple object creation (Rememberstatic foo
is not copied in every object, but is shared between multiple objects.)Scenario 3
Above
Modification-2
is from your question. In the above case, you are not changing the first referenced object, but you are adding content insidefoo
which is allowed. Compiler complains if you try to assign anew ArrayList()
to thefoo
reference variable.Rule If you have initialized a
final
variable, then you cannot change it to refer to a different object. (In this caseArrayList
)final classes cannot be subclassed
final methods cannot be overridden. (This method is in superclass)
final methods can override. (Read this in grammatical way. This method is in a subclass)