When you declare a variable final, you do not want anyone to change it. If the type of variable is primitive types, you can undoubtedly make it. Unfortunately, if the variable is a reference to an object, the "final" stuff you think may be not final!
class Test{
Â
 Test(int a, int b){
  this.a = a;
  this.b = b;
 }
 void set_ab(int a, int b){
  this.a = a;
  this.b = b;
 }
 void print_ab(){
  System.out.println("the value a is: "+this.a);
  System.out.println("the value b is: "+this.b);
 }
 private int a;
 private int b;
}
public class TestFinal1 {
Â
 public static void main(String[] args) {
       final Test mytest = new Test(1,2);
       mytest.print_ab();
       //now we change the value of a,b.
       mytest.set_ab(5, 6);
       mytest.print_ab();
      Â
   }
}
|
We can see that the value of a and b has been changed, which means that when you declare a reference final, it only means that the reference can not be changed but the contents it refer to can still be changed!
If you do not want to change a and b after they are initialized, the simplest approach is to declare a and b final:
 private final int a;  private final int b; |
But now you can not have setter method of a and b.
An alternative approach is to provide the clone method in the class. When you want do something about the object, you can use clone method to get a copy of original object. Now, you can do everything to this new object, and the original one will be never changed.
 public Test2 clone() throws CloneNotSupportedException{
  Test2 cloned = (Test2) super.clone();
  return cloned;
 }
|
Using final to declare the reference to an object is a potential security risk, because the contents of the object can still be changed.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
SEC37-J |
medium |
likely |
low |
P18 |
L1 |
TODO
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Chapter 6, Core Java⢠2 Volume I - Fundamentals, Seventh Edition