Java Specialists' Java Training Europehome of the java specialists' newsletter

The Java Specialists' Newsletter
Issue 192b2011-06-01 Category: Concurrency Java version: Java 5.0-7.0

Subscribe Free RSS Feed

How Does "this" Escape?

by Dr. Heinz M. Kabutz
Abstract:
A quick follow-up to the previous newsletter, to show how the ThisEscape class is compiled, causing the "this" pointer to leak.

When I posted the previous newsletter, I did not explicitly show how the "this" reference escapes implicitly. I have been showing these mysteries in my Java courses since 1999 and I forgot that there might be some mortals who have never seen a decompiled inner class ;-)

Our New Java Design Patterns Self-Study Course is Now Available

How Does "this" Escape?

When you construct a inner class within a non-static context, such as in a non-static method, a constructor or an initializer block, the class always has a pointer to the outer object.

Here again is our class ThisEscape:

import java.util.*;

public class ThisEscape {
  private final int num;

  public ThisEscape(EventSource source) {
    source.registerListener(
        new EventListener() {
          public void onEvent(Event e) {
            doSomething(e);
          }
        });
    num = 42;
  }

  private void doSomething(Event e) {
    if (num != 42) {
      System.out.println("Race condition detected at " +
          new Date());
    }
  }
}
  

When it gets compiled, javac generates two classes. The outer class looks like this:

import java.util.*;

public class ThisEscape {
  private final int num;

  public ThisEscape(EventSource source) {
    source.registerListener(new ThisEscape$1(this));
    num = 42;
  }

  private void doSomething(Event e) {
    if (num != 42)
      System.out.println(
          "Race condition detected at " + new Date());
  }

  static void access$000(ThisEscape _this, Event event) {
    _this.doSomething(event);
  }
}
  

Note how the compiler added the static, package access method access$000(). Note also how it passed a pointer to this into the constructor for the anonymous inner class ThisEscape$1.

Next we have the anonymous inner class. It is package access, with a package access constructor. Internally it maintains a reference to the ThisEscape object. Note: the anonymous class sets the this$0 field before calling super(). This is the only place where this is allowed in Java.

class ThisEscape$1 implements EventListener {
  final ThisEscape this$0;

  ThisEscape$1(ThisEscape thisescape) {
    this$0 = thisescape;
    super();
  }

  public void onEvent(Event e) {
    ThisEscape.access$000(this$0, e);
  }
}
  

Hopefully it is now clearer how the "this" pointer is implicitely leaked.

Kind regards from Crete

Heinz

Concurrency Articles Related Java Course Discuss at The Java Specialist Club

    
Your Name

Your E-Mail

Your Phone

Your Company

Your Comment


Java Master
Java Concurrency
Design Patterns
In-House Courses



© 2010 Heinz Kabutz - All Rights Reserved Sitemap seo web design Catch22 Marketing
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. JavaSpecialists.eu is not connected to Oracle, Inc. and is not sponsored by Oracle, Inc.