6

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."

Weishi Z
  • 1,629
  • 5
  • 18
  • 38
  • `System.out.println(Tracker.class.getName());` – Elliott Frisch Jul 15 '16 at 00:00
  • @ElliottFrisch What does it mean? Could you elaborate? – Weishi Z Jul 15 '16 at 00:09
  • You are creating (and asking about) naming shadows in an anonymous local class (you're also subclassing `Runnable`). Pick whichever name you want to figure out, and print it by getting the class. – Elliott Frisch Jul 15 '16 at 00:10
  • 1
    @ElliottFrisch No I'm not worried about the shadowing. `Tracker.super.track(event);` this runs in another thread! and track() is not a static method! So what does `Tracker.super` refers to? a class or a object? – Weishi Z Jul 15 '16 at 00:15
  • In your `run`, a `System.out.println(Tracker.super.getClass().getName());` would have said `test.Tracker` (because `Tracker.super` refers to the enclosing instance of `test.Tracker`, the one containing the anonymous local `Runnable` and that received the `Event` in question). I'm still curious, why did you name both classes `Tracker`? – Elliott Frisch Jul 15 '16 at 00:30

1 Answers1

3

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 {

...
@Override
  public void track(final Event event) {
    //anonymous class translated into local class
    class TrackerRunnable implements 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
      }
    }

    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.

Weishi Z
  • 1,629
  • 5
  • 18
  • 38
Darren Clark
  • 708
  • 7
  • 16