18 July 2007

java final vars != magic constant creator

In general, a lot of us tend to use the final keyword alongside public and static. Quite often too, we use it to declare a constant, perhaps a String, or int value. But, does the final keyword cause the variable to become a constant?

public class FinalExample {

public static final String CONSTANT =
"I can never change!";

}


Alright. We've got a constant. Let's try and make it not so constant:



public class FinalExample {

public static final String CONSTANT =
"I can never change!";

public static void main (String[] args) {
CONSTANT = "I can always change";
}

}

$ javac *.java
FinalExample.java:7: cannot assign a value to final variable CONSTANT
CONSTANT = "I can always change";
^
1 error

So the compiler enforces that you can't try to assign a value to a final variable. It didn't say anything about keeping it constant (that was the variable name). So, let's try and switch this up:

public class FinalExample {

public static final String[] CONSTANT_ARRAY =
{"I", "can", "never", "change"};

public static void main (String[] args) {
for (int x=0; x<CONSTANT_ARRAY.length; x++)
System.out.print(CONSTANT_ARRAY[x] + " ");
System.out.println();
}

}

$ java FinalExample
I can never change


This compiles and runs fine with the output as above. Let's try and break this.


public class FinalExample {

public static final String[] CONSTANT_ARRAY =
{"I", "can", "never", "change"};

public static void main (String[] args) {
CONSTANT_ARRAY[2] = "always";
for (int x=0; x<CONSTANT_ARRAY.length; x++)
System.out.print(CONSTANT_ARRAY[x] + " ");
System.out.println();
}

}

$ java FinalExample
I can always change


So, we just changed a final declared variable. Ok, let's try and change it a little differently.

public class FinalExample {

public static final String[] CONSTANT_ARRAY =
{"I", "can", "never", "change"};

public static void main (String[] args) {
CONSTANT_ARRAY =
{"I", "can", "always", "change"};
}

}

$ javac *.java
FinalExample.java:6: illegal start of expression
CONSTANT_ARRAY = {"I", "can", "always", "change"};
^
1 error


So, what gives?

  • Final declarations ensure that a declared variable is never re-assigned to something else. Once you go: final something = something, you don't get to say something = something_else later on.

  • In the event that your object is mutable- ie: can be changed, you are out of luck in trying to make it a constant using final. So, something like a Calendar object which has setters on it to change its value won't hold some magical constantness by being declared as final. This applies to array elements too, as demonstrated above.

No comments:

Post a Comment