Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The Java compiler is allowed to reorder the statements of the BankOperation() constructor so that the boolean flag initialized is set to true before the initialization has concluded. If it is possible to obtain a partially initialized instance of the class in a subclass using a finalizer attack (see OBJ04-J. Do not allow partially initialized objects to be accessed and CON26-J. Do not publish partially-constructed objects), a race condition can be exploited by invoking the getBalance() method to obtain the balance even though initialization is still underway.

...

This noncompliant code example consists of two classes: an immutable final ImmutablePoint class and a mutable Holder class. Holder is mutable because a new ImmutablePoint instance can be assigned to it using the setPoint() method (see CON09-J. Do not assume that classes having only immutable members are thread-safe). The ImmutablePoint is final so that an attacker may not subclass it and assign a mutable subclass to ipoint.

Code Block
bgColor#FFcccc
class Holder {
  ImmutablePoint ipoint;
  
  Holder(ImmutablePoint ip) {
   ipoint = ip;
  }
  
  ImmutablePoint getPoint() {
    return ipoint;
  }

  void setPoint(ImmutablePoint ip) {
    this.ipoint = ip;
  }
}

public final class ImmutablePoint {
  final int x;
  final int y;

  public ImmutablePoint(int x, int y) {
    this.x = x;
    this.y = y;
  }
}

...

Code Block
bgColor#ccccff
class Holder {
  volatile ImmutablePoint ipoint;
  
  Holder(ImmutablePoint ip) {
    ipoint = ip;
  }
  
  ImmutablePoint getPoint() {
    return ipoint;
  }

  void setPoint(ImmutablePoint ip) {
    this.ipoint = ip;
  }
}

The setPoint() method does not need to be synchronized because it operates atomically on immutable data, that is, on an instance of ImmutablePoint.

Declaring immutable fields as volatile Declaring immutable fields as volatile enables their safe publication in that, once published, it is impossible to change the state of the sub-object.

The setPoint() method does not currently need to be synchronized because it operates atomically on immutable data, that is, on an instance of ImmutablePoint. However, remember that the volatile keyword does not protect against TOCTOU race conditions. A routine that checked the current value of ipoint and subsequently set it would require additional locking to prevent the TOCTOU race condition. Such locking would render the volatile keyword unnecessary.

Noncompliant Code Example (partial initialization)

...