2016-04-30 10 views
0

Betrachten Sie den folgenden CodeWie funktioniert der Java-Compiler, wenn Sie eine Klasse `c` in sich haben?

public class myClass{ 
    myClass instanceOfNotYetDefinedClass; 
    ... //etc code 
} 

Ich verstehe nicht, wie der Compiler zu verstehen, dass verwaltet: Ich sage es, eine Klasse zu erstellen, und dann heißt es: „OK Lassen Sie mich sehen, was diese myClass! Klasse, Oh, es ist eine MyClass, lass mich sehen, was das hat ... "etc.

Es mag eine ziemlich noobish Frage sein, aber ich verstehe wirklich nicht, wie das gehandhabt werden könnte.

+0

Java ist OpenSource, schauen Sie sich den Quellcode an. ;-) – Vampire

+1

Compiler sprechen nicht so mit sich selbst. – ChiefTwoPencils

Antwort

1

Es gibt eine Reihe von Möglichkeiten, wie ein Compiler dies tun kann:

Ansatz # 1: Machen Sie zwei Pässe über den Parsing-Baum:

  • In Durchgang 1, alle Erklärungen finden und alle Umfang Grenzen und füllen Sie eine Symboltabelle .
  • In Pass 2 finden Sie alle Bezeichnerreferenzen und lösen sie anhand der Symboltabelle.

Ansatz # 2: einen einzigen Durchlauf über den Parsing-Baum Marke:

  • eine Symboltabelleneintrag erstellen, wenn eine Erklärung
  • angetroffen wird, wenn eine Kennung Referenz angetroffen wird:
    1. Versuchen Sie, es in der Symboltabelle
    2. aufzulösen, wenn die Auflösung fehlschlägt, fügen Sie es zu einer Liste hinzu, um später aufgelöst zu werden
  • Am Ende des Durchlaufs, besuche alle Identifikatoren in der Liste und versuche, sie erneut gegen die (jetzt vollständige) Symboltabelle aufzulösen.

Und es gibt Variationen und möglicherweise andere Ansätze.

Aber wenn Sie wirklich wissen wollen, wie der Java-Compiler eigentlich tut, schauen Sie sich den OpenJDK-Quellcode an.


Ein Verweis auf eine Klasse an sich ist eigentlich einfacher.In Ihrem Beispielcode "sieht" der Compiler den Parserbaumknoten für public class myClass, bevor er die Verwendung von myClass sieht. Wenn es auf Letzteres trifft, ist der Eintrag für myClass bereits in der Symboltabelle.


(In altmodischer Sprache wie C, die Erklärung und Definition einer Funktion kann getrennt sein, aber Sie können auf eine Kennung beziehen, wenn sie früher in der Übersetzungseinheit erklärt wurde.)


1 - Wenn Sie nicht wissen, was eine Symboltabelle ist, gibt es gute Bücher über Compiler und Compileraufbau.

2

Um zu sehen, was der Compiler macht, kompilieren Sie die Klasse mit javac und führen Sie javap darauf aus. Tun Sie dies mit Klasse gibt die folgenden:

public class myClass { 
    myClass instanceOfNotYetDefinedClass; 
    public myClass(); 
} 

Der public myClass(); ist ein Default-Konstruktor und ist hier irrelevant. Daraus können wir sehen, dass der Compiler nur ein Feld vom Typ myClass an myClass anhängt. Wie funktioniert das? Da myClass eine vorhandene Klasse im Gültigkeitsbereich des Codes ist, weiß der Compiler, dass er zur Laufzeit definiert wird. Sie lässt daher diese Definition einfach so, wie sie ist. Zur Laufzeit erhalten Sie beim Aufruf von myClass.instanceOfNotYetDefinedClass den Feldwert - entweder null, wenn Sie ihn nicht initialisieren, oder eine myClass Instanz, die ein eigenes Feld hat. Es gibt hier keine unendliche Rekursion oder einen Konflikt, es sei denn, du machst es z.B. Aufruf von new myClass() im Konstruktor.

Verwandte Themen