Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Edited

When you declare a variable is declared final, you do not want anyone to change itit is believed to be immutable. If the type of variable is a primitive typestype, you it can undoubtedly make it be made final. If the variable is a reference to an object, however, what you think is appears to be final may not always be.

Noncompliant Code Example

In this example, the value values of a and b has have been changed, which means that when you declare . When a reference is declared final, it only means signifies that the reference cannot be changed, but while the contents that it refers to can still be changed.

Code Block
bgColor#ffcccc
class TestFinalClass{

  TestFinalClass(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 TestFinal1FinalCaller {

  public static void main(String[] args) {
        final TestFinalClass mytestfc = new TestFinalClass(1,2);
        mytestfc.print_ab();
        //now we change the value of a,b.
        mytestfc.set_ab(5, 6);
        mytestfc.print_ab();

    }
}

Noncompliant Code Example

If you do not want to change a and b after they are initialized have to be kept immutable after their initialization, the simplest approach is to declare them as final:_.

Code Block
bgColor#ffcccc
void set_ab(int a, int b){ //But now compiler complains about set_ab method!
  this.a = a;
  this.b = b;
 }
 private final int a;
 private final int b;

But Unfortunately, now you one cannot have setter methods of a and b.

...

An alternative approach is to provide the a clone method in the class. When you want do something about the object, you can use the The clone method can be used to get a copy of an the original object. Now you one can do anything to this new object and without affecting the original one will never be changedobject.

Code Block
bgColor#ccccff
class NewFinal implements Cloneable
{
 NewFinal(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);
 }
 void set_ab(int a, int b){
  this.a = a;
  this.b = b;
 }
 public NewFinal clone() throws CloneNotSupportedException{
  NewFinal cloned = (NewFinal) super.clone();
  return cloned;
 }
 private int a;
 private int b;
}

public class Test2NewFinalCaller {

  public static void main(String[] args) {
        final NewFinal mytestnf = new NewFinal(1,2);
        mytestnf.print_ab();
         //get the copy of original object
    try {
          NewFinal mytest2nf2 = mytestnf.clone();
           //now we change the value of a,b of the copy.
         mytest2 nf2.set_ab(5, 6);
	         //but the original value will not be changed
	          mytestnf.print_ab();
    } catch (CloneNotSupportedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  }
}

One Another common mistake about this is to use a public static final array. Clients will be able to can trivially modify the contents of the array (although they will not be able to change the array itself, as it is final).

...

Code Block
bgColor#ccccff
private static final SomeType [] THE_THINGS = { ... };
public static final List<SomeType> SOMETHINGS =
&#xA0; Collections.unmodifiableList(Arrays.asList(THE_THINGS));

Now neither the original array values nor the public list can be modified by a any client.

Risk Assessment

Using final to declare the reference to an object is a potential security risk because the contents of the object can still be changed.

...