Weishi Zeng Weishi Zeng - 4 months ago 13
Java Question

Java - super keyword in new thread Runnable - refers non static method thru class

In all the

super
keyword tutorials I found online, it's hard to get any examples closer to following one.
My question:


  1. What's the difference between
    Tracker.super.track(event);
    and
    test.parent.Tracker.track(event);
    ?

  2. Why would the first work?

  3. What does
    Tracker.super
    refers to? A object or a class?



subclass:

package test;

public class Tracker extends test.parent.Tracker {


@Override
public void track(final Event event) {
Executor.execute(new Runnable() {
public void run() {
Tracker.super.track(event); //this works!! why??
super.track(event); // compile error: cannot resolve
test.parent.Tracker.track(event); //compile error: can only reference static method
}
});
}

}


super class

package test.parent;

public abstract class Tracker {

public void track(Event event) {}

}


Reference Updates:

In jls8, 15.11.2

"Suppose that a field access expression T.super.f appears within class C, and the immediate superclass of the class denoted by T is a class whose fully qualified name is S. If f in S is accessible from C, then T.super.f is treated as if it had been the expression this.f in the body of class S. Otherwise, a compile-time error occurs.

Thus, T.super.f can access the field f that is accessible in class S, even if that field is hidden by a declaration of a field f in class T.

It is a compile-time error if the current class is not an inner class of class T or T itself."

Answer

Your run() method is in an anonymous subclass of Runnable where it is also an inner class of Tracker.

Effectively the same as

package test;

public class Tracker extends test.parent.Tracker {

  private class TrackerRunnable extends Runnable {
    public void run(){
      Tracker.super.track(event);  //this works!! why??
      super.track(event); // compile error: cannot resolve
      test.parent.Tracker.track(event);  //compile error: can only reference static method
    }
  }

...
@Override
  public void track(final Event event) {
    Executor.execute(new TrackerRunnable()); 
  }
}

In Java an inner class also has a reference to the outer class that it "belongs" to. You would reference this for TrackerRunnable as this inside of run, but if you need to access the instance of Tracker that the TrackerRunnable is associated with you would access it as Tracker.this. Same thing with Tracker.super. Just super means the superclass of TrackerRunnable not Tracker (in this case Runnable).

The main thing to note is that this is syntax that is used for scope resolution only in inner classes, and that the Tracker here refers to "The instance of the Tracker class that I belong to". In the case of test.parent.Tracker.track Tracker refers to "the Tracker class", so you can't call instance members on the class itself.