final
means the value of a
won't change. But, depending on type, the value of a
might actually be the address of an object (in the question it was just an int
so value was not an address, just a 1). Locking down the address a
holds doesn't lock down the object. Designing the object to be immutable will.
Favorite metaphor for this is a briefcase with a 1 in it. An immutable design will lock the briefcase so people can't get inside and change the 1. final
will handcuff it to your wrist so people can't slip you a new briefcase with something else in it. You need both if you want to be sure nothing can happen to your 1.
But that just goes for objects.
If you're a primitive (like int
) there is no briefcase. You are not holding it's handle (address). You're just holding the 1 in your hand.
If you're a final
primitive the 1 has been fused to your hand. You can't let go. You can't pick up anything else.
Object or primitive, what final
means is the same. Whatever you hold, an address or a value, you hold it until you die.
If the value of int a above can still be changed even after declaring it as final, what is the point of final?
It can't.
...they declare most of their variables as final, but the motivation behind doing so just doesn't make sense to me.
Calling an identifier a variable when it's been declared final
is really just a common bad habit. If it's final, it's not variable. It doesn't change. It's a constant.
There are a few motivations for creating constants. Semantic correctness is one.
is a constant (3.14159...) so it doesn't make sense to go changing it's value. Another motivation is to protect against mistakes that cause bugs. Variables are often reused and so assigned new values. A constant is protected from unintended changes. The more you can protect against bad code the better.