Monday, May 21, 2007

Java : Final is not constant ?

Java doesn’t have anything like C++ const. You might think that final is like const, but it’s not:
  • A final variable in Java can be assigned to only once, but if the variable is a reference-type, you can still change what it refers to. Fun!
  • A const variable in C++ can be assigned to only once, where it’s declared, and nothing is allowed to change about the value, whether it’s an object or not. Now that is a nice feature!
This is what Java Language Specification talks about the final variable.

A variable can be declared final. A final variable may only be assigned to once. It is a compile time error if a final variable is assigned to unless it is definitely unassigned (§16) immediately prior to the assignment.

A blank final is a final variable whose declaration lacks an initializer.

Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object. This applies also to arrays, because arrays are objects; if a final variable holds a reference to an array, then the components of the array may be changed by operations on the array, but the variable will always refer to the same array.

Declaring a variable final can serve as useful documentation that its value will not change and can help avoid programming errors.

In the example:

class Point {
int x, y;
int useCount;
Point(int x, int y) { this.x = x; this.y = y; }
final static Point origin = new Point(0, 0);
the class Point declares a final class variable origin. The origin variable holds a reference to an object that is an instance of class Point whose coordinates are (0, 0). The value of the variable Point.origin can never change, so it always refers to the same Point object, the one created by its initializer. However, an operation on this Point object might change its state-for example, modifying its useCount or even, misleadingly, its x or y coordinate.


Douglas Myers-Turnbull said...

I'm glad someone was willing to point this out. One thing, though: your two bullet points refer to one concept. Perhaps you could note that or remove the bullets? This is a very useful topic—too many beginning Java developers don't realize this! Thanks.

Kinjal The Hero said...

Awesome post... Loved it....

rpbarbati said...

Hmmm - I guess that means that using final on an object reference is also a really easy way to create a singleton.


avineesh said...

Sry i didn't get what is dB/W final and constant
plz tell me any body

Carlos Ferreira said...

The non-existence of const creates a big problem in java, because it breaks the encapsulation property of the objects.

Since 90% of the Java programers implement getters like

public final getA(){
return this.a;

the reference of the "this.a" will be exposed to the outside, without any control over object modification.

A correct implementation of the getter, that protects the object attribute, would be:

public final getA(){
return this.a.clone();