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.
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
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. –
domanda di stackoverflow correlata: http://stackoverflow.com/questions/1220914/in-which-language-java-compiler-jvm-and-java-is-written – jvdneste