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