...
Wiki Markup According to the Java Language Specification \[[JLS 05|AA. Java References#JLS 05]\] Section 12.6.2 ""Finalizer Invocations are Not Ordered"":
This can be a problem as slow running finalizers tend to block others in the queue.Wiki Markup The Java programming language imposes no ordering on {{finalize}} method calls. Finalizers \[of different objects\] may be called in any order, or even concurrently.
...
| Code Block | ||
|---|---|---|
| ||
class BaseClass {
protected void finalize() throws Throwable {
System.out.println(""Superclass finalize!"");
doLogic();
}
public void doLogic() throws Throwable {
System.out.println(""This is super-class!"");
}
}
class SubClass extends BaseClass {
private Date d; // mutable instance field
protected SubClass() {
d = new Date();
}
protected void finalize() throws Throwable {
System.out.println(""Subclass finalize!"");
try {
// cleanup resources
d = null;
} finally {
super.finalize(); // Call BaseClass's finalizer
}
}
public void doLogic() throws Throwable{
// any resource allocations made here will persist
// inconsistent object state
System.out.println(""This is sub-class! The date object is: "" + d); // 'd' is already null
}
}
public class BadUse {
public static void main(String[] args) {
try {
BaseClass bc = new SubClass();
// Artificially simulate finalization (do not do this)
System.runFinalizersOnExit(true);
} catch (Throwable t) {
// Handle error
}
}
}
|
...
| Code Block | ||
|---|---|---|
| ||
class BaseClass {
protected void finalize() throws Throwable {
System.out.println(""superclass finalize!"");
// Eliminate the call to the overridden doLogic().
}
...
}
|
...
| Wiki Markup |
|---|
Alternatively, a more expensive solution is to declare an anonymous class so that the {{finalize()}} method is guaranteed to run for the superclass. This solution is applicable to {{public}} non-final classes. ""The finalizer guardian object forces {{super.finalize}} to be called if a subclass overrides {{finalize()}} and does not explicitly call {{super.finalize}}"". \[[JLS 05|AA. Java References#JLS 05]\] |
...
| Wiki Markup |
|---|
\[[JLS 05|AA. Java References#JLS 05]\] Section 12.6, Finalization of Class Instances \[[API 06|AA. Java References#API 06]\] [finalize()|http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#finalize()] \[[Bloch 08|AA. Java References#Bloch 08]\] Item 7, Avoid finalizers \[[Darwin 04|AA. Java References#Darwin 04]\] Section 9.5, The Finalize Method \[[Flanagan 05|AA. Java References#Flanagan 05]\] Section 3.3, Destroying and Finalizing Objects \[[Coomes 07|AA. Java References#Coomes 07]\] "Sneaky""Sneaky" Memory Retention \[[Boehm 05|AA. Java References#Boehm 05]\] \[[MITRE 09|AA. Java References#MITRE 09]\] [CWE ID 586|http://cwe.mitre.org/data/definitions/586.html] ""Explicit Call to Finalize()"", [CWE ID 583|http://cwe.mitre.org/data/definitions/583.html] ""finalize() Method Declared Public"", [CWE ID 568|http://cwe.mitre.org/data/definitions/568.html] ""finalize() Method Without super.finalize()"" |
...
OBJ01-J. Understand how a superclass can affect a subclass 08. Object Orientation (OBJ) OBJ03-J. Be aware that a final reference may not always refer to immutable data