Running on Java 17-ea+15-1230 (Preview)
Home of The JavaSpecialists' Newsletter

192bHow Does "this" Escape?

Author: Dr. Heinz M. KabutzDate: 2011-06-01Java Version: 5Category: Concurrency
 

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

We have three upcoming LIVE virtual classes in April and May 2021:

  1. Refactoring to Streams and Lambdas for US$ 497 on April 6-7 2021 @ 9am-1pm Frankfurt Time.
  2. Extreme Java - Advanced Topics Java 17 Edition for EUR 1299 on April 19-20 2021 @ 9am-5pm Frankfurt Time. (almost sold out)
  3. Design Patterns Deep Dive for US$ 497 on May 11-12 2021 @ 7-11am Los Angeles Time.

My favourite course at the moment is the Refactoring to Streams and Lambdas course. We spend 8 hours ripping apart a 330k LOC application and replacing bits with more modern code. Too much fun! We still have a few places available for next week. The Advanced Topics Course is also very interesting. It is almost sold out though, so please grab the seats if you would like to join.

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

 

Comments

We are always happy to receive comments from our readers. Feel free to send me a comment via email or discuss the newsletter in our JavaSpecialists Slack Channel (Get an invite here)

When you load these comments, you'll be connected to Disqus. Privacy Statement.

Related Articles

Browse the Newsletter Archive

About the Author

Heinz Kabutz Java Conference Speaker

Java Champion, author of the Javaspecialists Newsletter, conference speaking regular... About Heinz

Superpack 21

Superpack 21 Our entire Java Specialists Training in one huge bundle more...

Free Java Book

Dynamic Proxies in Java Book
Java Training

We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.

Java Consulting

We can help make your Java application run faster and trouble-shoot concurrency and performance bugs...

Java Emergency?

If your system is down, we will review it for 15 minutes and give you our findings for just 1 € without any obligation.