You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 24 Next »

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 final. If the variable is a reference to an object, however, what you think is final may not be.

Noncompliant Code Example

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

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();

    }
}

Noncompliant Code Example

If you do not want to change a and b after they are initialized, the simplest approach is to declare them final:_

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 now you cannot have setter methods of a and b.

Compliant Solution

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

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 Test2 {

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

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

Noncompliant Code Example

With this declaration, SOMETHINGS[1], etc. can be modified by clients of the code.

public static final SomeType [] SOMETHINGS = { ... };

Compliant Solution

One approach is to make use of the above method: first define a private array and then provide a public method that returns a copy of the array:

private static final SomeType [] SOMETHINGS = { ... };
public static final SomeType [] somethings() {
  return SOMETHINGS.clone();
}

Now the original array values cannot be modified by a client.

Compliant Solution

An alternative approach is to have a private array from which a public immutable list is constructed:

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 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.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

OBJ03-J

medium

likely

medium

P9

L2

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

Chapter 6, Core Javaâ„¢ 2 Volume I - Fundamentals, Seventh Edition by Cay S. Horstmann, Gary Cornell
Publisher:Prentice Hall PTR;Pub Date:August 17, 2004


OBJ02-J. Avoid using finalizers      06. Objects Orientation (OBJ)      OBJ31-J. Misusing public static variables

  • No labels