Final variable manipulation in Java
Solution 1
It means that if your final variable is a reference type (i.e. not a primitive like int), then it's only the reference that cannot be changed. It cannot be made to refer to a different object, but the fields of the object it refers to can still be changed, if the class allows it. For example:
final StringBuffer s = new StringBuffer();
The content of the StringBuffer can still be changed arbitrarily:
s.append("something");
But you cannot say:
s = null;
or
s = anotherBuffer;
On the other hand:
final String s = "";
Strings are immutable - there simply isn't any method that would enable you to change a String (unless you use Reflection - and go to hell).
Solution 2
If you have a final reference to a Java object you can still manipulate it but cannot change its reference. For instance this code is perfectly legal:
import javax.swing.JLabel;
class Test1 {
private final static JLabel l = new JLabel("Old text");
public static void main(String[] args) {
System.err.println(l.getText());
l.setText("New Text");
System.err.println(l.getText());
}
}
But you can't say:
l = new JLabel("Newest Text");
After the first assignment to l. Note that you can do this though:
import javax.swing.JLabel;
class Test1 {
public static void main(String[] args) {
final JLabel l;
String s = getArbitaryString(); // Assume this method returns a string
l = new JLabel(s);
System.err.println(l.getText());
}
}
This can be done because when l is declared it is not assigned to anything not even null. So you are allowed to assign something to it one time only.
Same thing goes for primitives. You can assign a value to it like this:
class Test1 {
public static void main(String[] args) {
final int i;
i = 2;
}
}
But now you cannot manipulate it further since the only thing you can do to primitive types is to assign values to them.
Solution 3
You cannot change what object or value a final variable refers to. You can only assign a final variable once.
This has no effect on whether you can change the state of the object. The object itself can still be manipulated unless it is coded in such a way that this manipulation is forbidden. An immutable object is an object whose state cannot change.
Solution 4
As others have said, it means that you can manipulate the object the variable points at, but you cannot change the reference (i.e. assign another object to the variable).
Objects that are mutable by design, such as a List
can be changed (you can add elements to them) whereas if you have an immutable object such as a String
or Integer
you won't be able to change it (all the operations the class String
supports return a new instance, and don't modify the actual object).
Related videos on Youtube
![Cassie](https://i.stack.imgur.com/S0p6q.jpg?s=256&g=1)
Cassie
Updated on August 04, 2020Comments
-
Cassie almost 4 years
Could anyone please tell me what is the meaning of the following line in context of Java:
final variable can still be manipulated unless it's immutable
As far as I know, by declaring any variable as final, you can't change it again, then what they mean with the word immutable in above line?
-
Mohammad Taha almost 15 yearsYou can but that's not what he meant.
-
Aviad Ben Dov almost 15 yearsActually, you can't. You would get a java.lang.IllegalAccessException.
-
polygenelubricants over 14 yearsNo you can't. You get
java.lang.IllegalAccessException: Can not set final [type] field [fieldname] to [type of new value]
. -
polygenelubricants over 14 yearsIt's documented here too: java.sun.com/docs/books/tutorial/reflect/member/… -- "IllegalAccessException when Modifying Final Fields"
-
Stephen C over 14 years@polygenelubricants - java.sun.com/javase/6/docs/api/java/lang/reflect/… says this: "If the underlying field is final, the method throws an IllegalAccessException unless setAccessible(true) has succeeded for this field and this field is non-static."
-
polygenelubricants over 14 years@Stephen C: thanks for pointing this out! I'm still learning and this is new to me. Very surprising. I will do my research now.
-
Michael Borgwardt over 12 years@pramodc84: It's the same for all variables. Most collections are mutable though.
-
Daniel Magnusson over 11 yearsSo how can I change it with reflection? =)
-
Michael Borgwardt over 11 years@Daniel Magnusson: use docs.oracle.com/javase/7/docs/api/java/lang/reflect/… to make the private
char[]
insideString
accessible. -
luigi7up over 11 years+1 unless you use Reflection - and go to hell - just love a good humor coming from a bad experience :)))
-
Viraj over 8 yearsIs the following code valid ? If yes, How ? It works for me. final Task newTask[] = new Task[1]; newTask[0] = someMethod(); if(!newTask[0].isCompleted()){ newTask[0] = null; }
-
Michael Borgwardt over 8 years@Viraj: In Java, only variables can be final, not objects. So in your code, final only applies to the reference newTask. But the array object which it refers to can sill have its elements changed.