2016-07-14 3 views
5

In allen super Keyword-Tutorials fand ich online, es ist schwer, irgendwelche Beispiele näher an folgende zu bekommen. Meine Frage:Java - Super-Schlüsselwort im neuen Thread Runnable - bezieht sich nicht statische Methode durch Klasse

  1. Was ist der Unterschied zwischen Tracker.super.track(event); und test.parent.Tracker.track(event);?

  2. Warum sollte das erste funktionieren?

  3. Was bedeutet Tracker.super? Ein Objekt oder eine Klasse?

Unterklasse:

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

} 

Superklasse

package test.parent; 

public abstract class Tracker { 

public void track(Event event) {} 

} 

Referenz Updates:

In jls8, 15.11.2

"Angenommen, ein Feldzugriffsausdruck T.super.f erscheint innerhalb der Klasse C und die unmittelbare Oberklasse der mit T bezeichneten Klasse ist eine Klasse, deren voll qualifizierter Name S ist. Wenn f in S von C aus zugänglich ist, dann T. super.f wird behandelt, als wäre es der Ausdruck this.f im Rumpf der Klasse S. Andernfalls tritt ein Fehler bei der Kompilierung auf.

So kann T.super.f das Feld f zugreifen, die in der Klasse S zugänglich ist, auch wenn das Feld durch eine Erklärung eines Feldes f in der Klasse T.

versteckt

Es ist ein Fehler bei der Kompilierung, wenn die aktuelle Klasse selbst „nicht eine innere Klasse der Klasse T oder T ist.

+0

'System.out.println (Tracker.class.getName()); ' –

+0

@ElliottFrisch Was ist das? Könnten Sie das näher ausführen? –

+0

Sie erstellen (und fragen) nach Benennungsschatten in einer anonymen lokalen Klasse (Sie bilden auch eine Unterklasse von "Runnable"). Wählen Sie den Namen, den Sie herausfinden möchten, und drucken Sie ihn aus, indem Sie die Klasse abrufen. –

Antwort

3

Ihre run() Methode ist in einer anonymen Unterklasse von Runnable, wo es auch eine inneren Klasse von Tracker.

Effektiv

die gleiche wie

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 eine innere Klasse auch einen Verweis auf die äußere Klasse hat, dass es zu „gehört“. Sie würden innerhalb von run TrackerRunnable für TrackerRunnable als this referenzieren, aber wenn Sie auf die Instanz von Tracker zugreifen müssen, die mit TrackerRunnable verknüpft ist, würden Sie darauf als Tracker.this zugreifen. Das gleiche gilt für Tracker.super. Nur super bedeutet die Oberklasse von TrackerRunnable nicht Tracker (in diesem Fall Runnable).

Die wichtigste Sache zu beachten ist, dass diese Syntax, die nur für Umfang Auflösung verwendet wird, in inneren Klassen, und dass die Tracker bezieht sich hier auf „Die Instanz der Tracker Klasse, die ich gehöre“. Im Fall test.parent.Tracker.track bezieht sich Tracker auf die Klasse "Tracker", sodass Sie Instanzmitglieder nicht für die Klasse selbst aufrufen können.

+1

'Nicht-statische innere' ist eine Tautologie, – EJP

+0

Mein schlechtes auf die Terminologie von "statisch verschachtelte Klasse" vs. "innere Klasse". Feste Antwort. –

+0

@Pshemo Was EJP bedeutet ist, was er sagte, und es ist in der JLS angegeben. Ich zitiere keine nicht normativen Quellen. – EJP

Verwandte Themen