According to the Java Language Specification, §15.8.3, this [JLS 2005]:
When used as a primary expression, the keyword
thisdenotes a value that is a reference to the object for which the instance method was invoked (§15.12), or to the object being constructed. The type ofthisis the classCwithin which the keywordthisoccurs. At run time, the class of the actual object referred to may be the classCor any subclass ofC.
...
- Returning
thisfrom a non-private, overridable method that is invoked from the constructor of a class whose object is being constructed. (For more information, see rule MET05-J. Ensure that constructors do not call overridable methods.) - Returning
thisfrom a nonprivate method of a mutable class, which allows the caller to manipulate the object's state indirectly. This commonly occurs in method-chaining implementations; see rule VNA04-J. Ensure that calls to chained methods are atomic for more information. - Passing
thisas an argument to an alien method invoked from the constructor of a class whose object is being constructed. - Using inner classes. An inner class implicitly holds a reference to the instance of its outer class unless the inner class is declared static.
- Publishing by assigning
thisto a public static variable from the constructor of a class whose object is being constructed. - Throwing an exception from a constructor. Doing so may cause code to be vulnerable to a finalizer attack; see rule OBJ11-J. Be wary of letting constructors throw exceptions for more information.
- Passing internal object state to an alien method. This enables the method to retrieve the
thisreference of the internal member object.
...
Inner classes maintain a copy of the this reference of the outer object. Consequently, the this reference could leak outside the scope [Goetz 2002]. This noncompliant code example uses a different implementation of the DefaultExceptionReporter class. The constructor uses an anonymous inner class to publish an exception reporter.
...
Use a private constructor and a public static factory method to safely publish the exception reporter from within the constructor [Goetz 2006a].
| Code Block | ||
|---|---|---|
| ||
public class DefaultExceptionReporter implements ExceptionReporter {
private final DefaultExceptionReporter defaultER;
private DefaultExceptionReporter(ExceptionReporter excr) {
defaultER = new DefaultExceptionReporter(excr) {
public void report(Throwable t) {
// report exception
}
};
}
public static DefaultExceptionReporter newInstance(
ExceptionReporter excr) {
DefaultExceptionReporter der = new DefaultExceptionReporter(excr);
excr.setExceptionReporter(der.defaultER);
return der;
}
// Default implementations of setExceptionReporter() and report()
}
|
...
The new thread can access the this reference of the current object [Goetz 2002], [Goetz 2006a]. Notably, the Thread() constructor is alien to the ThreadStarter class.
...
TSM01-EX0: It is safe to create a thread in the constructor, provided the thread is not started until after object construction is complete, because a call to start() on a thread happens-before any actions in the started thread [JLS 2005].
Even though this code example creates a thread that references this in the constructor, the thread is started only when its start() method is called from the startThread() method [Goetz 2002], [Goetz 2006a].
| Code Block | ||
|---|---|---|
| ||
final class ThreadStarter implements Runnable {
Thread thread;
public ThreadStarter() {
thread = new Thread(this);
}
public void startThread() {
thread.start();
}
@Override public void run() {
// ...
}
}
|
TSM01-EX1: Use of the ObjectPreserver pattern [Grand 2002] described in rule TSM02-J. Do not use background threads during class initialization is safe and is permitted.
...
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
TSM01-J | medium | probable | high | P4 | L3 |
Bibliography
[JLS 2005] | Keyword |
| |
Section 3.2, Publication and Escape | |
Chapter 5, Creational Patterns, Singleton |
...
| Tasklist | ||||
|---|---|---|---|---|
| ||||
||Completed||Priority||Locked||CreatedDate||CompletedDate||Assignee||Name|| |T|M|F|1270219843973|1270221864972|svoboda|"*Inner classes* implicitly hold a reference to the instance of the outer class, unless the inner class is declared as static." => Change inner classes to "An inner class implicitly holds ... "| |T|M|F|1270220129871|1270755934790|rcs|"Note that this code also violates CON32-J. Protect accessible mutable static fields from untrusted code" => Not sure if I agree because the class is package-private and inaccessible to untrusted code| |T|M|F|1270733657099|1271021912028|rcs_mgr|"A Runnable object's constructor may construct a Thread object around itself, as long as the thread is not actually started in the Runnable object's constructor." => I still think this info is redundant.| |
...