Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: made CS into NCE, added CS

...

Because, the field is nonvolatile and nonfinal, the statements within the constructor can be reordered by the compiler in such a way that the this reference is published before the initialization statements are executed.

Compliant Solution

Noncompliant Code Example (visibility of partially initialized object)

This noncompliant code example This compliant solution declares the pub field as volatile and reduces the accessibility of the static class field to package-private so that untrusted callers beyond the current package cannot obtain the this instance. More importantly, the constructor publishes the this reference after initialization has concluded.

Code Block
bgColor#ccccff#FFcccc
class Publisher {
  static volatile Publisher pub;
  int num;

  Publisher(int number) {
    // Initialization 
    this.num = number;
    // ...
    pub = this;
  }
}

The constructor publishes the this reference after initialization has concluded. However, it is unsuitable because a legit caller can see the default value of the field, before it is initialized (a violation of CON26-J. Do not publish partially-constructed objects).

If the pub field is not declared as volatile initialization statements may be reordered. The Java compiler does not allow declaring the static pub field as final in this case.

Compliant Solution (public static factory method)

This compliant solution removes the internal field and provides a newInstance() factory method which can be used to obtain an instance of the Publisher object. This ensures that threads do not see a compromised Publisher instance.

Code Block
bgColor#ccccff

class Publisher {
  final int num;

  private Publisher(int number) {
    // Initialization 
    this.num = number;
  }
  
  public static Publisher newInstance(int number) {
    Publisher pu = new Publisher(number);  
    return pu;
  }
}

Noncompliant Code Example (handlers)

...

This issue can also occur when a listener is prematurely published. Consequently, it will start receiving event notifications even before the subclass's initialization has concluded.

Compliant Solution

This compliant solution defines a method setReporter() in class MyExceptionReporter. The method explicitly calls the superclass's setExceptionReporter() method, publishing a reference to its own Class object. It is not permissible to publish the reference in the constructor for MyExceptionReporter for reasons noted earlier in the noncompliant code example.

...

The problem occurs because the this reference of the outer class is published by the inner class so that other threads can see it. If the class is subclassed, the issue described in the previous noncompliant code example resurfaces.

Compliant Solution

Wiki Markup
A {{private}} constructor alongside a {{public}} factory method can be used to safely publish the {{filter()}} method from within the constructor \[[Goetz 06|AA. Java References#Goetz 06]\].

...

Wiki Markup
This allows the new thread to access the {{this}} reference of the current object \[[Goetz 02|AA. Java References#Goetz 02], [Goetz 06|AA. Java References#Goetz 06]\].

Compliant Solution

Wiki Markup
In this compliant solution, even though the thread is created in the constructor, it is not started until its {{start()}} method is called from method {{startThread()}} \[[Goetz 02|AA. Java References#Goetz 02], [Goetz 06|AA. Java References#Goetz 06]\].

...