en Java, sur la compilation, nous obtenons un fichier .class pour chaque classe (y compris des classes ni des interfaces imbriquées) définies dans le fichier source.
Quelle est la raison de cette génération de fichiers multiples.
Est-ce pour simplifier la réutilisation de la classe?
Pourquoi ne pas générer une .Class pour un fichier .java? p>
3 Réponses :
Le JVM doit être capable de trouver le code pour une classe donnée, compte tenu de son nom. S'il n'y a potentiellement aucune relation entre le nom de fichier source et le nom de fichier de code, et que vous souhaitez que le nom du fichier de code soit basé sur le nom de fichier source em>, comment vous attendriez-vous à charger le code? P>
Par exemple: Supposons que je voudrais compiler foo.java qui contient une barre de classe. P>
Une autre classe fait ensuite référence à la barre, la JVM a donc besoin du code pour cela ... Comment suggéreriez-vous qu'il trouve le fichier? p>
Notez que, dans .NET, il existe une unité de déploiement distincte appelée assembly em> - et une référence à un type inclut également le nom de l'assemblage, mais c'est légèrement différent de ce que vous proposiez. < / p>
C'est une décision de conception concernant une unité de compilation faite par les développeurs. Les classes compilées sont généralement combinées dans un fichier JAR. P>
Extrait de Spécification de langue Java p>
7.3 Unités de compilation CompilationUnit est le symbole de l'objectif (§2.1) pour la grammaire syntaxique (§2.3) de Programmes Java. p>
Les types déclarés dans différentes unités de compilation peuvent dépendre de l'autre, circulairement. Un compilateur Java doit organiser pour compiler tous ces types en même temps. Strong> p>
En réponse à la question rhétorique de @jon Skeet: p>
Une autre classe fait ensuite référence à la barre, la JVM a donc besoin du code pour cela ... Comment suggéreriez-vous qu'il trouve le fichier? p> blockQuote>
Supposons (hypothétiquement) que le format Java Classfile représentait des classes imbriquées / intérieures en les intégrant dans le fil de classe pour la classe la plus externe. Le nom binaire de la barre est "
lsome / pkg / foo $ bar; code>". Le chargeur de classe pourrait em> diviser le nom au caractère "$ code>", utilisez la première partie pour localiser le fichier de classe pour foo, puis accédez à la représentation de la classe de barres intégrée. < / p>Je pense que la vraie raison que les classes intérieures / nichées ont des camps de classe distincts est historique. IIRC, Java 1.0 n'a pas soutenu les classes imbriquées ou intérieures, et les formats de classe de classe correspondants n'ont donc pas besoin de les traiter. Lorsque Java 1.1 a été créé (soutenir les classes intérieures / imbriquées), Sun voulait que le format de classe de classe soit compatible avec les camarades de classe produits par le compilateur Java 1.0. Ils ont donc choisi d'implémenter des classes intérieures / nichées sous forme de camarades de classe distinctes, à l'aide du caractère réservé "
$ code>" dans le nom de classe binaire. p>Une deuxième raison possible est que le format plat simplifie le chargement de la classe par rapport à un format intégré hypothétique. P>
Et enfin, il y avait (et toujours) aucune raison convaincante de ne pas utiliser de format de fichier plat. Cela crée peut-être un peu de gratter de la tête mineure lorsque un programmeur souhaite charger des classes intérieures à l'aide de
class.forname () code> mais c'est assez rare ... et la solution est simple. P>
Le dernier paragraphe est sur place, je pense. Java Déjà i> a un format de conteneur pouvant regrouper plusieurs classes (et ressources) dans un seul fichier. Pourquoi introduire la même fonctionnalité à un autre niveau aussi?
Le fait que 1 classe Java soit stockée dans exactement 1 fichier de class et que 1 fichier de class contienne exactement 1 classe (type, en fait, il peut également s'agir d'une interface, d'une annotation ou d'une énumération) simplifie la manipulation et le chargement des deux classes et des fichiers .class.