web-dev-qa-db-fra.com

Comment s'effectue exactement la compilation Java Java?

Confus par Java processus de compilation

OK je sais ceci: nous écrivons Java le code source, le compilateur indépendant de la plateforme le traduit en bytecode, puis le jvm qui dépend de la plateforme le traduit en code machine.

Donc, dès le début, nous écrivons Java code source. Le compilateur javac.exe est un fichier .exe. Quel est exactement ce fichier .exe? Le compilateur Java n'est-il pas écrit en Java, alors comment se fait-il qu'il existe un fichier .exe qui l'exécute? Si le code du compilateur est écrit en Java, alors comment se fait-il que le code du compilateur soit exécuté au stade de la compilation, puisque c'est le travail du jvm d'exécuter le code Java. Comment une langue peut-elle compiler elle-même son propre code de langue? Tout cela me semble être un problème de poulet et d'oeufs.

Maintenant, que contient exactement le fichier .class? Est-ce un arbre de syntaxe abstrait sous forme de texte, est-ce une information tabulaire, qu'est-ce que c'est?

quelqu'un peut-il me dire de manière claire et détaillée comment mon code source Java est converti en code machine.

58
nash

OK je sais ceci: nous écrivons Java le code source, le compilateur indépendant de la plateforme le traduit en bytecode,

En fait, le compilateur lui-même fonctionne comme un exécutable natif (d'où javac.exe). Et c'est vrai, il transforme le fichier source en bytecode. Le bytecode est indépendant de la plate-forme, car il vise la machine virtuelle Java.

puis le jvm qui dépend de la plate-forme le traduit en code machine.

Pas toujours. Quant à la JVM de Sun, il existe deux jvms: client et serveur. Ils peuvent tous les deux, mais ne doivent certainement pas compiler en code natif.

Donc, dès le départ, nous écrivons Java code source. Le compilateur javac.exe est un fichier .exe. Quel est exactement ce fichier .exe? Le compilateur Java n'est-il pas écrit en Java, alors comment se fait-il qu'il existe un fichier .exe qui l'exécute?

Ce fichier exe est un bytecode Java encapsulé. C'est pour plus de commodité - pour éviter les scripts batch complexes. Il démarre une JVM et exécute le compilateur.

Si le code du compilateur est écrit en Java, alors comment se fait-il que le code du compilateur soit exécuté au stade de la compilation, puisque c'est le travail du jvm d'exécuter le code Java.

C'est exactement ce que fait le code d'emballage.

Comment une langue peut-elle compiler son propre code de langue? Tout cela me semble être un problème de poulet et d'oeufs.

C'est vrai, déroutant à première vue. Cependant, ce n'est pas seulement l'idiome de Java. Le compilateur d'Ada est également écrit en Ada lui-même. Cela peut ressembler à un "problème de poulet et d'oeufs", mais en vérité, ce n'est qu'un problème d'amorçage.

Maintenant, que contient exactement le fichier .class? Est-ce un arbre de syntaxe abstrait sous forme de texte, est-ce une information tabulaire, qu'est-ce que c'est?

Ce n'est pas un arbre de syntaxe abstraite. AST n'est utilisé que par le tokenizer et le compilateur au moment de la compilation pour représenter le code en mémoire. Le fichier .class Est comme un assembly, mais pour JVM. JVM, à son tour, est une machine abstraite qui peut exécuter un langage machine spécialisé - ciblé uniquement sur la machine virtuelle. Dans sa plus simple expression, le fichier .class A une structure très similaire à l'assemblage normal. Au début, il y a toutes les variables statiques déclarées, puis vient quelques tableaux de signatures de fonctions externes et enfin le code machine.

Si vous êtes vraiment curieux, vous pouvez creuser dans le fichier de classe en utilisant l'utilitaire "javap". Voici un exemple de sortie (obscurcie) de l'appel de 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

Vous devriez donc déjà avoir une idée de ce que c'est vraiment.

quelqu'un peut-il me dire de manière claire et détaillée comment mon code source Java est converti en code machine.

Je pense que cela devrait être plus clair en ce moment, mais voici un bref résumé:

  • Vous appelez javac pointant vers votre fichier de code source. Le lecteur (ou tokenizer) interne de javac lit votre fichier et en construit un AST réel. Toutes les erreurs de syntaxe proviennent de cette étape.

  • Le javac n'a pas encore terminé son travail. Quand il a le AST la vraie compilation peut commencer. Il utilise le modèle de visiteur pour parcourir AST et résout les dépendances externes pour ajouter du sens (sémantique) au code. Le produit fini est enregistré dans un fichier .class Contenant du bytecode.

  • Il est maintenant temps d'exécuter la chose. Vous appelez Java avec le nom du fichier .class. Maintenant, la JVM redémarre, mais pour interpréter Votre code. La machine virtuelle Java peut ou non compiler votre bytecode abstrait dans l'assembly natif. Le compilateur HotSpot de Sun en conjonction avec la compilation Just In Time peut le faire si nécessaire. Le code en cours d'exécution est constamment profilé par la JVM et recompilé en code natif si certaines règles sont respectées. Le plus souvent, le code hot est le premier à être compilé en mode natif.

Edit: Sans javac, il faudrait invoquer le compilateur en utilisant quelque chose de similaire à ceci:

%JDK_HOME%/bin/Java.exe -cp:myclasspath com.Sun.tools.javac.Main fileToCompile

Comme vous pouvez le voir, il appelle l'API privée de Sun, il est donc lié à l'implémentation de Sun JDK. Cela en rendrait les systèmes de construction dépendants. Si l'un est passé à un autre JDK (le wiki en répertorie 5 autres que Sun), le code ci-dessus doit être mis à jour pour refléter le changement (car il est peu probable que le compilateur réside dans le package com.Sun.tools.javac). D'autres compilateurs pourraient être écrits en code natif.

La méthode standard consiste donc à expédier le wrapper javac avec JDK.

59
Rekin

Le compilateur Java n'est-il pas écrit en Java, alors comment se fait-il qu'il existe un fichier .exe qui l'exécute?

D'où obtenez-vous ces informations? L'exécutable javac peut être écrit dans n'importe quel langage de programmation, il n'est pas pertinent, tout ce qui est important c'est que c'est un exécutable qui tourne .Java fichiers dans .class des dossiers.

Pour plus de détails sur la spécification binaire d'un fichier .class, vous pouvez trouver ces chapitres dans Java Language Specification utiles (bien que peut-être un peu techniques):

Vous pouvez également jeter un oeil à la Virtual Machine Specification qui couvre:

16
matt b

Le compilateur javac.exe est un fichier .exe. Quel est exactement ce fichier .exe? Le compilateur Java n'est-il pas écrit en Java, alors comment se fait-il qu'il existe un fichier .exe qui l'exécute?

Le Java (au moins celui fourni avec le JDK Sun/Oracle) est en effet écrit en Java. javac.exe n'est qu'un lanceur qui traite les arguments de la ligne de commande, dont certains sont transmis à la JVM qui exécute le compilateur, et d'autres au compilateur lui-même.

Si le code du compilateur est écrit en Java, alors comment se fait-il que le code du compilateur soit exécuté au stade de la compilation, puisque c'est le travail du jvm d'exécuter Java code. Comment un langage peut-il compiler le sien code de langue? Tout cela me semble être un problème de poulet et d'oeufs.

De nombreux compilateurs (sinon la plupart) sont écrits dans la langue qu'ils compilent. De toute évidence, à un stade précoce, le compilateur lui-même devait être compilé par autre chose, mais après ce "bootstrapping", toute nouvelle version du compilateur peut être compilée par une version plus ancienne.

Maintenant, que contient exactement le fichier .class? Est-ce un arbre de syntaxe abstrait sous forme de texte, est-ce une information tabulaire, qu'est-ce que c'est?

Les détails du format de fichier de classe sont décrits dans la spécification Java Virtual Machine .

11
Michael Borgwardt

Eh bien, javac et jvm sont généralement des binaires natifs. Ils sont écrits en C ou autre. Il est certainement possible de les écrire en Java, il vous suffit tout d'abord d'avoir une version native. C'est ce qu'on appelle le "boot strapping".

Fait amusant: la plupart des compilateurs qui compilent en code natif sont écrits dans leur propre langage. Cependant, ils devaient tous d'abord avoir une version native écrite dans une autre langue (généralement C). Le premier compilateur C, par comparaison, a été écrit en assembleur. Je suppose que le premier assembleur a été écrit en code machine. (Ou, en utilisant des papillons ;)

Les fichiers .class sont des bytecodes générés par javac. Ils ne sont pas textuels, ils sont du code binaire similaire au code machine (mais avec un jeu d'instructions et une architecture différents).

Le jvm, au moment de l'exécution, a deux options: il peut soit interpréter le code d'octet (se faisant passer pour un CPU lui-même), soit JIT (juste à temps) le compiler en code machine natif. Ce dernier est plus rapide, bien sûr, mais plus complexe.

5
Mike Caron

Le fichier .class contient un bytecode qui est une sorte de comme très Assembly de haut nivea . Le compilateur pourrait très bien être écrit en Java, mais la JVM devrait être compilée en code natif pour éviter le problème poulet/œuf. Je crois qu'il est écrit en C, tout comme les niveaux inférieurs des bibliothèques standard. Lorsque la JVM s'exécute, elle effectue une compilation juste à temps pour transformer ce bytecode en instructions natives.

3
ZoFreX

Brève explication

Écrivez du code sur un éditeur de texte, enregistrez-le dans un format que le compilateur comprend - ". Java" extension de fichier, javac (compilateur Java) le convertit en " .class " fichier de format (code octet - fichier de classe). JVM exécute le fichier .class sur le système d'exploitation sur lequel il se trouve.

Explication longue

Rappelez-vous toujours Java n'est pas le langage de base que le système d'exploitation reconnaît. Java le code source est interprété par le traducteur appelé Java Virtual Machine (JVM. JVM ne peut pas comprendre le code que vous écrivez dans un éditeur, il a besoin de code compilé. C'est là qu'un compilateur entre en image.

Chaque processus informatique se livre à la manipulation de la mémoire. Nous ne pouvons pas simplement écrire du code dans un éditeur de texte et le compiler. Nous devons le mettre dans la mémoire de l'ordinateur, c'est-à-dire le sauvegarder avant de le compiler.

Comment le javac (compilateur Java) reconnaîtra-t-il le texte enregistré comme celui à compiler? - Nous avons un format de texte distinct que le compilateur reconnaît, c'est-à-dire . Java. Enregistrez le fichier dans l'extension .Java et le compilateur le reconnaîtra et le compilera à la demande.

Que se passe-t-il lors de la compilation? - Le compilateur est un deuxième traducteur (pas un terme technique) impliqué dans le processus, il traduit le langage compris par l'utilisateur (Java) en langage compris par la JVM (code octet - format .class).

Que se passe-t-il après la compilation? - Le compilateur produit un fichier .class que JVM comprend. Le programme est ensuite exécuté, c'est-à-dire que le fichier .class est exécuté par JVM sur le système d'exploitation.

Faits que vous devez savoir

1) Java n'est pas multi-plateforme c'est indépendant de la plateforme.

2) La JVM est développée en utilisant C/C++. L'une des raisons pour lesquelles les gens appellent Java un langage plus lent que C/C++

3) Java octet code (.class) est en "Assembly Language", le seul langage compris par JVM. Tout code qui produit un fichier .class lors de la compilation ou généré Le code octet peut être exécuté sur la JVM.

2

Windows ne sait pas comment appeler les programmes Java avant d'installer un runtime Java, et Sun a choisi d'avoir des commandes natives qui collectent les arguments, puis invoquent la JVM à la place). de lier le suffixe jar au moteur Java.