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

GitHub 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 ;-)

NEW: We have revised our "Advanced Topics" course, covering Reflection, Java NIO, Data Structures, Memory Management and several other useful topics for Java experts to master. 2 days of extreme fun and learning. Extreme Java - Advanced Topics.

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

Extreme Java - Concurrency and Performance for Java 8
Extreme Java - Advanced Topics for Java 8
Design Patterns
In-House Courses

© 2010-2016 Heinz Kabutz - All Rights Reserved Sitemap
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.