2010-08-04 13 views
49

Confuso da processo di compilazione javaCome avviene esattamente la compilazione java?

OK so che questo: Scriviamo il codice sorgente di Java, il compilatore, che è indipendente dalla piattaforma traduce in bytecode, quindi la JVM, che dipende dalla piattaforma lo traduce in codice macchina.

Fin dall'inizio, scriviamo il codice sorgente java. Il compilatore javac.exe è un file .exe. Che cosa è esattamente questo file .exe? Non è il compilatore java scritto in java, quindi come mai c'è un file .exe che lo esegue? Se il codice del compilatore è scritto è java, allora come viene eseguito il codice del compilatore in fase di compilazione, poiché è il lavoro di jvm per eseguire il codice java. Come può un linguaggio stesso compilare il proprio codice lingua? Sembra tutto un problema di pollo e uova per me.

Ora che cosa contiene esattamente il file .class? È un albero sintattico astratto in forma di testo, è informazione tabellare, che cos'è?

qualcuno può dirmi in modo chiaro e dettagliato su come il mio codice sorgente Java viene convertito in codice macchina.

+0

Una lingua può facilmente compilare il proprio codice lingua. I compilatori C/C++ sono spesso scritti in C o C++, il compilatore del linguaggio cobra è scritto in cobra e ci sono molti esempi di compilatori http://en.wikipedia.org/wiki/Self-hosting. – jcao219

+4

Il compilatore non deve essere indipendente dalla piattaforma, deve solo conformarsi alle specifiche che specificano solo input e output. Potresti scrivere un compilatore in perl per il codice bytecode risultante. –

+0

domanda di stackoverflow correlata: http://stackoverflow.com/questions/1220914/in-which-language-java-compiler-jvm-and-java-is-written – jvdneste

risposta

54

OK so che questo: Scriviamo il codice sorgente di Java, il compilatore, che è indipendente dalla piattaforma traduce in bytecode,

In realtà il compilatore stesso lavora come un eseguibile nativo (quindi javac.exe). E vero, trasforma il file sorgente in bytecode. Il bytecode è indipendente dalla piattaforma, poiché è indirizzato a Java Virtual Machine.

quindi il jvm che dipende dalla piattaforma lo traduce in codice macchina.

Non sempre. Per quanto riguarda la JVM di Sun, esistono due jvms: client e server. Entrambi possono, ma non certamente, compilare il codice nativo.

Fin dall'inizio, scriviamo il codice sorgente java. Il compilatore javac.exe è un file .exe. Che cosa è esattamente questo file .exe? Non è il compilatore java scritto in java, quindi come mai c'è un file .exe che lo esegue?

Questo file exe è un bytecode java incapsulato. È per comodità - per evitare complicati script di batch. Avvia una JVM ed esegue il compilatore.

Se il codice compilatore è scritto è Java, quindi come mai il codice del compilatore viene eseguito in fase di compilazione, fin dalla sua il lavoro della JVM per eseguire codice Java.

Questo è esattamente ciò che fa il codice a capo.

Come può un linguaggio stesso compilare il proprio codice lingua? Sembra tutto un problema di pollo e uova per me.

Vero, confuso a prima vista. Tuttavia, non è solo l'idioma di Java. Il compilatore di Ada è anche scritto in Ada stessa. Può sembrare un "problema di pollo e uova", ma in realtà è solo un problema di bootstrap.

Ora che cosa contiene esattamente il file .class? È un albero sintattico astratto in forma di testo, è informazione tabellare, che cos'è?

Non si tratta di Abstract Syntax Tree. AST viene utilizzato da tokenizer e compilatore solo al momento della compilazione per rappresentare il codice in memoria. Il file .class è come un assembly, ma per JVM. A sua volta, JVM è una macchina astratta in grado di eseguire un linguaggio macchina specializzato, mirato solo alla macchina virtuale. Nel suo caso più semplice, il file .class ha una struttura molto simile al normale assemblaggio. All'inizio vengono dichiarate tutte le variabili statiche, quindi vengono aggiunte alcune tabelle delle firme delle funzioni esterne e infine il codice della macchina.

Se siete veramente curiosi, potete scavare nel classfile usando l'utilità "javap". Ecco campione (offuscato) Uscita di invocare javap -c Main:

0: new #2; //class SomeObject 
3: dup 
4: invokespecial #3; //Method SomeObject."<init>":()V 
7: astore_1 
8: aload_1 
9: invokevirtual #4; //Method SomeObject.doSomething:()V 
12: return 

così si dovrebbe avere un'idea già quello che realmente è.

qualcuno può dirmi in modo chiaro e dettagliato su come il mio codice sorgente Java viene convertito in codice macchina.

penso che dovrebbe essere più chiaro in questo momento, ma qui è breve riassunto:

  • Invochi javac che punta al file di codice sorgente. Il lettore interno (o tokenizer) di javac legge il file e ne crea un vero e proprio AST. Tutti gli errori di sintassi provengono da questo stadio.

  • Il javac non ha ancora finito il lavoro. Quando ha l'AST, può iniziare la vera compilazione. Sta usando il pattern visitor per attraversare AST e risolve dipendenze esterne per aggiungere significato (semantica) al codice. Il prodotto finito viene salvato come file .class contenente bytecode.

  • Ora è il momento di eseguire la cosa. Si invoca java con il nome di .classfile. Ora la JVM ricomincia, ma a interpreta il codice. La JVM può o non può compilare il tuo bytecode astratto nell'assembly nativo. Il compilatore HotSpot di Sun in combinazione con la compilazione Just In Time può farlo se necessario. Il codice in esecuzione viene costantemente profilato dalla JVM e ricompilato nel codice nativo se vengono rispettate determinate regole. Più comunemente il codice hot è il primo a compilare in modo nativo.

Edit: Senza la javac si dovrebbe invocare il compilatore utilizzando qualcosa di simile a questo:

%JDK_HOME%/bin/java.exe -cp:myclasspath com.sun.tools.javac.Main fileToCompile 

Come si può vedere sta chiamando privato API di Sun quindi è destinato alla realizzazione Sun JDK. Renderebbe dipendenti i sistemi di costruzione. Se si passa a un altro JDK (le liste wiki 5 diverse da quelle di Sun), il codice sopra riportato deve essere aggiornato per riflettere la modifica (poiché è improbabile che il compilatore risieda nel pacchetto com.sun.tools.javac). Altri compilatori potrebbero essere scritti in codice nativo.

Quindi il modo standard è spedire il wrapper javac con JDK.

+2

Quindi ecco lo scenario da quello che hai descritto, scriviamo il codice sorgente. javac.exe è l'eseguibile, esiste principalmente per raccogliere i parametri e avviare la JVM. La JVM esegue quindi il codice compilatore (raccolta di un gran numero di file .class già compilati). Il compilatore esegue quindi il nostro programma scritto. Anche quando il compilatore è stato progettato, un altro linguaggio (C nel nostro caso) viene utilizzato per creare i file .class per il compilatore. ho ragione con quello che ho detto? Il file .exe è un bytecode java spostato? Non è esattamente il codice avvolgente. che tipo di script batch complicati stai parlando? – nash

+3

Corretto, 'javac' è solo un involucro conveniente. Il vero codice del compilatore è nel pacchetto 'com.sun.tools.javac' di Sun's JDK. Puoi andare lì e dare un'occhiata al codice sorgente - può essere interessante vedere gli interni. Puoi anche invocare il compilatore 'javac' direttamente da Java, senza chiamare alcun processo esterno. Se si tiene conto di ciò, è logico che 'javac' sia solo un lanciatore di alcuni file di classe sepolti all'interno di JDK. Posso solo sospettare, ma credo che sia sufficiente avviare JVM e passare gli argomenti. – Rekin

+0

E riguardo allo script batch, dai un'occhiata all'ultimo paragrafo della risposta. L'ho modificato per rispondere al tuo commento. – Rekin

3

Il file .class contiene il codice byte che è una sorta di come molto high-level Assembly. Il compilatore potrebbe benissimo essere scritto in Java, ma la JVM dovrebbe essere compilata in codice nativo per evitare il problema dell'uovo/pollo. Credo che sia scritto in C, come lo sono i livelli inferiori delle librerie standard. Quando viene eseguita la JVM, esegue la compilazione just-in-time per trasformare quel bytecode in istruzioni native.

13

Non è il compilatore java scritto in java, quindi come mai c'è un file .exe che lo esegue?

Da dove vengono visualizzate queste informazioni? L'eseguibile javac può essere scritto in qualsiasi linguaggio di programmazione, è irrilevante, tutto ciò che è importante è che è un eseguibile che trasforma i file .java in file .class.

Per i dettagli sulla specifica binario di un file .class si potrebbe trovare questi capitoli nel Java Language Specification utile (anche se forse un po 'tecnico):

È può anche dare un'occhiata al Virtual Machine Specification che copre:

+0

Verificherà i collegamenti. Più lo scenario che ho aggiunto come commento alla risposta di rekin. Sono d'accordo? – nash

4

Bene, javac e la JVM sono in genere binari nativi. Sono scritti in C o simili. È certamente possibile scriverli in Java, basta prima aver bisogno di una versione nativa. Questo è chiamato "boot strapping".

Un fatto divertente: la maggior parte dei compilatori che compilano codice nativo sono scritti nella loro lingua. Tuttavia, tutti dovevano avere una versione nativa scritta in un'altra lingua prima (di solito C). Il primo compilatore C, per confronto, è stato scritto in Assembler. Presumo che il primo assemblatore sia stato scritto in codice macchina.(Oppure, using butterflies;)

. I file di classe sono bytecode generato da javac. Non sono testuali, sono codice binario simile al codice macchina (ma, con un set di istruzioni e un'architettura differenti).

Il jvm, in fase di esecuzione, ha due opzioni: Può interpretare il codice byte (fingendo di essere una CPU stessa), oppure può JIT (just-in-time) compilarlo nel codice macchina nativo. Quest'ultimo è più veloce, ovviamente, ma più complesso.

+0

Grazie per l'XKCD ..non l'avevo visto :) –

+0

Tecnicamente, il primo compilatore potrebbe essere creato da un * interprete * scritto in un altro linguaggio, sebbene le linee tra interpretazione e compilazione JIT siano un po 'sfocate poiché alla fine entrambi producono codice macchina nativo. –

+0

Vero. In effetti, ci sono anche opzioni più pazze. Il primo compilatore C++ era semplicemente un traduttore che produceva il codice C da usare con un compilatore C. –

-1

Il compilatore è stato originariamente scritto in C con bit di C++ e presumo che lo sia ancora (perché pensi che il compilatore sia scritto anche in Java?). javac.exe è solo il codice C/C++ che è il compilatore.

Come punto laterale potresti scrivere il compilatore in java, ma hai ragione, devi evitare il problema dell'uovo e della gallina. Per fare ciò normalmente scrivere uno o più strumenti di bootstrap in qualcosa come C per poter compilare il compilatore.

Il file .class contiene i bytecode, l'output del processo di compilazione javac e queste sono le istruzioni che indicano alla JVM cosa fare. Durante il runtime questi bytecode sono tradotti in istruzioni CPU native (codice macchina) in modo che possano essere eseguiti sull'hardware specifico sotto JVM.

Per complicare un po 'questo, la JVM ottimizza anche e memorizza nella cache il codice macchina prodotto dai bytecode per evitare di tradurli ripetutamente. Questo è noto come compilazione JIT e si verifica quando il programma è in esecuzione e i bytecode vengono interpretati.

+2

È risaputo che il compilatore Java (Sun/Oracle) è scritto in Java. A partire da Java 6, c'è persino un'API sufficiente, ma molto tempo prima, la gente lo chiamava tramite l'API non ufficiale nei pacchetti sun.tools. –

+0

Bene, impari qualcosa di nuovo ogni giorno. – Paolo

10

Il compilatore javac.exe è un file .exe. Che cosa è esattamente questo file .exe? Non è il compilatore java scritto in java, allora come mai c'è il file .exe che lo esegue ?

Il compilatore Java (almeno quello fornito con Sun/Oracle JDK) è scritto in Java. javac.exe è solo un programma di avvio che elabora gli argomenti della riga di comando, alcuni dei quali vengono passati alla JVM che esegue il compilatore e altri al compilatore stesso.

Se il codice compilatore è scritto è Java, quindi come mai il codice del compilatore è eseguito in fase di compilazione, fin dalla sua il lavoro della JVM per eseguire codice Java. Come può una lingua compilare autonomamente il proprio codice lingua? Sembra tutto un problema di pollo e uova per me.

Molti (se non la maggior parte) compilatori sono scritti nella lingua che compilano. Ovviamente, in alcune fasi iniziali il compilatore stesso doveva essere compilato da qualcos'altro, ma dopo questo "bootstrap", qualsiasi nuova versione del compilatore può essere compilata da una versione precedente.

Ora che cosa contiene esattamente il file .class ? È un albero sintattico astratto in forma di testo, è tabulare informazioni, che cos'è?

I dettagli del formato file di classe sono descritti nello Java Virtual Machine specification.

+0

"Il compilatore Java (almeno quello fornito con Sun/Oracle JDK) è scritto in Java" Non lo sapevo! Grazie Signore. – ZoFreX

1

Windows non sa come richiamare i programmi Java prima di installare un runtime Java, e Sun ha scelto di avere comandi nativi che raccolgono argomenti e quindi invocano la JVM invece di legare il suffisso jar al motore Java.

+0

Non in CMD.EXE per quanto ne so. Non puoi semplicemente dire "foobar.jar" sulla riga commadn e farlo eseguire. Questo potrebbe essere un limite di Windows 95/98/ME in COMMAND.EXE che ha portato a tale decisione. In questi giorni sarebbe carino comunque. –

-3
  1. di file .java
  2. compilatore (BUILD JAVA)
  3. .class (bytecode)
  4. JVM (software di sistema di solito costruire con 'C')
  5. piattaforma operativa
  6. PROCESSORE
2

Breve Spiegazione

Scrivere un codice su un editor di testo, salvarlo in un formato comprensibile dal compilatore - ".java " estensione del file, javac (java compilatore) converte in " .class" file di formato (byte di codice - file di classe). JVM esegue il file .class sul sistema operativo che si siede su

.

lunga spiegazione

ricordate sempre Java non è la lingua di base che il sistema operativo riconosce. codice sorgente Java viene interpretato al sistema operativo da un traduttore chiamato Java Virtual Machine (JVM). JVM riesco a capire il codice in cui scrivi un editor, ha bisogno di codice compilato. È qui che entra in gioco un compilatore.

Ogni processo del computer indulge nella manipolazione della memoria. Non possiamo semplicemente scrivere il codice in un editor di testo e compilarlo. Dobbiamo metterlo nella memoria del computer, e salvarlo prima di compilarlo.

In che modo il javac (compilatore java) riconosce il testo salvato come quello da compilare? - Abbiamo un formato di testo separato che il compilatore riconosce, cioè .java. Salva il file nell'estensione .java e il compilatore lo riconoscerà e lo compila quando richiesto.

Cosa succede durante la compilazione? - Il compilatore è un secondo traduttore (non un termine tecnico) coinvolto nel processo, traduce il linguaggio compreso dall'utente (java) nella lingua capita da JVM (codice Byte - formato .class).

Cosa succede dopo la compilazione? - Il compilatore produce file .class che JVM comprende. Il programma viene quindi eseguito, cioè il file .class viene eseguito da JVM sul sistema operativo.

Fatti che dovreste sapere

1) Java non è multi-piattaforma è indipendente dalla piattaforma.

2) JVM è sviluppato utilizzando C/C++. Uno dei motivi per cui la gente chiama Java un linguaggio più lento di/C++

3) Java bytecode C (.class) è in "in linguaggio Assembly", l'unico linguaggio compreso da JVM. Qualsiasi codice che produca il file .class sulla compilazione o il codice Byte generato può essere eseguito su JVM.

Problemi correlati