2015-05-29 11 views
11

die folgende Verzeichnisstruktur Gegeben:Wie javac automatisch kompilieren Abhängigkeiten einer Klasse

/top 
    |--- wrk 
      |--- pkg 
        |--- A.java 
        |--- B.java 

wird angenommen, dass die beiden Dateien A.java und B.java den folgenden Code enthalten jeweils:

// Filename: A.java 
package pkg; 
class A { B b; } 

// Filename: B.java 
package pkg; 
class B {...} 

Unter der Annahme, dass die aktuelles Verzeichnis ist /top/wrk

Warum funktioniert der Befehl javac -cp . pkg/A.java Arbeitserfolg lly, obwohl wir noch nicht B.java kompiliert haben?

Auch wenn das aktuelle Verzeichnis /top/wrk/pkg ist, dann funktioniert der Befehl javac A.java. Wie das?

+0

Die Antwort liegt in http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html#BHCCHDGH. Keine Zeit, dies hier in Form einer Antwort kurz zu formulieren: Es sucht auch nach Quelldateien im Klassenpfad. – Marco13

+0

Ich kann das nicht reproduzieren. Es kann nicht auf meinem Computer kompiliert werden. Bist du sicher, dass B noch nie kompiliert wurde? –

+0

Es ist eine Mac/Windows-Sache. Sehen Sie meine bearbeitete und nun (hoffentlich) definitive Antwort für weitere Details. –

Antwort

7

Warum funktioniert der Befehl javac -cp? pkg/A.java Arbeit erfolgreich, obwohl haben wir noch nicht B.java zusammengestellt

Wenn Sie A.java kompilieren, wird der Compiler B.java auch kompilieren, da beide A.java und B.java im selben Paket sind. Dies funktioniert auch wenn B.java war in einem anderen Paket von A.java (sofern B ist öffentlich), solange beide Pakete in der wrk Verzeichnis vorhanden sind und Sie kompilieren A.java von wrk Verzeichnis.

Vom Oracle documentation für javac:

Wenn die -sourcepath Option nicht angegeben ist, wird der Benutzer Klassenpfad auch für Quelldateien gesucht.

Vom Oracle document für CLASSPATH

Der Standardwert für den Klassenpfad ist ""

Wenn Sie kein CLASSPATH eingestellt haben, wird es zu . vorbelegt werden. Anschließend wird sourcepath auch . sein, da der Standard sourcepath derselbe wie der CLASSPATH ist. Sie können bestätigen, dass der Standard-Quellpfad auf . festgelegt ist, indem Sie A.java mit javac -verbose -g pkg\A.java kompilieren.Beachten Sie, dass der Compiler im aktuellen Verzeichnis für .java Dateien suchen:

[parsing started pkg\A.java] [parsing completed 29ms] [search path for source files: [.]]

Um zu bestätigen, dass die sourcepath-CLASSPATH eingestellt ist, können Sie versuchen, die CLASSPATH Wechsel mit der -cp Option durch A.java Kompilieren javac -cp C:\ -verbose -g pkg\A.java verwenden. A.java kompiliert diese Zeit nicht, da Sie die CLASSPATH zu C:\ überschrieben haben, und das ist, was sourcepath standardmäßig auch wird. Dies ist die Ausgabe:

[parsing started pkg\A.java] [parsing completed 26ms] [search path for source files: [C:\]] pkg\A.java:3: cannot find symbol symbol : class B

Auch wenn das aktuelle Verzeichnis/top/WRK/Pkg dann der Befehl javac A.java arbeitet. Wie das?

Dies wird nicht unabhängig von Arbeit, ob B.class in pkg

Haftungsausschluss vorhanden ist: Ich kann dieses Verhalten nur auf Windows bestätigen, aber ich bezweifle sehr, dass es auf anderen Betriebssystemen anders sein sollte.

+0

Können Sie einen Link zu den Javac-Dokumenten angeben, die dieses Verhalten angeben? Ich konnte nichts anderes finden als durch Angabe von -sourcepath. –

+0

@PhilAnderson Siehe meine Bearbeitung. Wahrscheinlich haben Sie einen Wert in 'CLASSPATH' eingestellt, so dass Ihr' sourcepath' nicht standardmäßig auf '.' steht. – CKing

+0

Danke Chetan, aber ich habe nichts im CLASSPATH. –

1

Der Compiler muss entweder eine Quelle für B finden und erfolgreich kompilieren oder eine Klasse für B finden, auch wenn es nur ein Import ist. Im Gegensatz zum Laden, was dynamisch gemacht wird.

Suchen Sie in Ihrem Ausgabeverzeichnis und Sie werden sehen, dass B ebenfalls kompiliert wurde. Es wird auch in einem anderen Paket kompiliert, aber Sie müssen es öffentlich machen, um es von A zu referenzieren.

1

Vom Oracle javac docs ...

Wenn Sie die -sourcepath Option gesetzt ist, dann sucht der Compiler den angegebenen Pfad für Quelldateien. Andernfalls durchsucht der Compiler den Klassenpfad für Klassen- und Quelldateien. Unter Windows scheint die Option -sourcepath standardmäßig aktiviert zu sein, und Ihr Befehl funktioniert. obwohl

Auf meinem Mac, es schlägt fehl und gibt folgende Meldung ...

A.java:5: error: cannot find symbol 
    B b; 
    ^
    symbol: class B 
    location: class A 
1 error 

Um es automatisch zu erhalten, um Quelldateien von Abhängigkeiten zu suchen und zusammenstellen, müßten Sie die -sourcepath Option verwenden. z ...

javac -sourcepath ./* A.java
+0

Siehe meine Antwort. Ich glaube, der Quellpfad ist standardmäßig auf 'CLASSPATH' gesetzt und es besteht die Möglichkeit, dass' CLASSPATH' auf Ihrem Rechner gesetzt ist. – CKing

Verwandte Themen