Why can final object be modified?
final
simply makes the object reference unchangeable. The object it points to is not immutable by doing this. INSTANCE
can never refer to another object, but the object it refers to may change state.
How does the final keyword in Java work? (I can still modify an object.)
You are always allowed to initialize a final
variable. The compiler makes sure that you can do it only once.
Note that calling methods on an object stored in a final
variable has nothing to do with the semantics of final
. In other words: final
is only about the reference itself, and not about the contents of the referenced object.
Java has no concept of object immutability; this is achieved by carefully designing the object, and is a far-from-trivial endeavor.
Final object can be modified but reference variable cannot be changed
You can't change final value using "=" operator. If you do it, you try to change the reference (or primitive) and final
states that this cannot be changed.
You can change existing object's fields:
public static final User user = NewUser(145);
public static void main(String[] args)
{
user.setId(155);
}
Why an object marked as final can be modified and call non-final method in Java?
Referencing Erik's answer in comments, I found an easy explanation for C++ programmers.
Pet pet;
in Java is like Pet* pet;
in C++.
final Pet pet;
in Java is like Pet * const pet;
in C++ which makes the pointer const
but not the value itself.
Note that there is a subtle difference in Java and C++.
In C++, you have to assign a value when declaring a const
variable but in Java, it lets you do it later but only once.
final object in java
Using the "final" keyword makes the the variable you are declaring immutable. Once initially assigned it cannot be re-assigned.
However, this does not necessarily mean the state of the instance being referred to by the variable is immutable, only the reference itself.
There are several reasons why you would use the "final" keyword on variables. One is optimization where by declaring a variable as final allows the value to be memoized.
Another scenario where you would use a final variable is when an inner class within a method needs to access a variable in the declaring method. The following code illustrates this:
public void foo() {
final int x = 1;
new Runnable() {
@Override
public void run() {
int i = x;
}
};
}
If x is not declared as "final" the code will result in a compilation error. The exact reason for needing to be "final" is because the new class instance can outlive the method invocation and hence needs its own instance of x. So as to avoid having multiple copies of a mutable variable within the same scope, the variable must be declared final so that it cannot be changed.
Some programmers also advocate the use of "final" to prevent re-assigning variables accidentally where they should not be. Sort of a "best practice" type rule.
Can we change the value of a final variable of a mutable class?
final
does not enforce any degree of constancy of the object to which a reference is referring (it is not the same as const
in C++).
When you mark a variable as final
, it means that you cannot assign a different object reference to that variable.
For example, this code will not compile:
final StringBuffer s=new StringBuffer("a");
s = new StringBuffer("another a"); /*not possible to reassign to s*/
It can be useful when using Runnables, Callables and locking idioms.
final variables can't be reassigned, but the object can be mutated in flutter
Consider the following class:
class SampleObject {
int id;
String value;
SampleObject(this.id, this.value);
}
final variable can't be reassigned:
void main() {
final obj1 = SampleObject(1, "value1");
// the following line will gives error:
// The final variable 'obj1' can only be set once
obj1 = SampleObject(1, "value2");
}
But the object property can be changed (is mutable):
void main() {
final obj1 = SampleObject(1, "value1");
obj1.value = "value2";
print(obj1.value);
}
But it becomes an immutable object if you set all the property in the class to final:
class SampleObject {
final int id;
final String value;
SampleObject(this.id, this.value);
}
where it gives error when you're trying to reassign a value to its property:
void main() {
final obj1 = SampleObject(1, "value1");
// the following line will gives error:
// 'value' can't be used as a setter because it's final.
// Try finding a different setter, or making 'value' non-final
obj1.value = "value2";
}
Using the final modifier whenever applicable in Java
I think it all has to do with good coding style. Of course you can write good, robust programs without using a lot of final
modifiers anywhere, but when you think about it...
Adding final
to all things which should not change simply narrows down the possibilities that you (or the next programmer, working on your code) will misinterpret or misuse the thought process which resulted in your code. At least it should ring some bells when they now want to change your previously immutable thing.
At first, it kind of looks awkward to see a lot of final
keywords in your code, but pretty soon you'll stop noticing the word itself and will simply think, that-thing-will-never-change-from-this-point-on (you can take it from me ;-)
I think it's good practice. I am not using it all the time, but when I can and it makes sense to label something final
I'll do it.
Related Topics
Implementation Difference Between Aggregation and Composition in Java
Java.Lang.Verifyerror: Expecting a Stackmap Frame at Branch Target Jdk 1.7
How to Get a Unicode Character's Code
Arrays.Aslist(Int[]) Not Working
What Is the Purpose of the Java Constant Pool
How to Write an Arraylist of Strings into a Text File
How to Test If My Font Is Rendered Correctly in PDF
Why Can't We Use '==' to Compare Two Float or Double Numbers
Why Can't We Use '==' to Compare Two Float or Double Numbers
Loading a Text File into a Textarea
Java Equivalent to #Region in C#
Inter Thread Communication in Java
Simple Hibernate Query Returning Very Slowly
Jackson: How to Prevent Field Serialization