Pourquoi Java n'autorise-t-il pas l'utilisation d'en-têtes comme en C ++


18

J'ai une question pour laquelle je n'ai pas trouvé de réponse à l'exception de la réponse suivante qui ne répond pas à mes exigences:

"Parce que James Gosling ne voulait pas"

Je sais que Java peut avoir des interfaces (uniquement des fonctions virtuelles pures, pas d'attributs), mais ce n'est pas exactement la même chose que les définitions de classe.


14
Quelle est la raison pour laquelle vous les voulez?

19
Pour avoir plus de temps pour les combats à l'épée;)
dan04

6
Je suppose que la plupart des développeurs C ++ aimeraient se débarrasser du moteur de remplacement de texte vieux de 40 ans qui duplique des centaines de kLoC pour chaque fichier cpp, ce qui entraîne de longs temps de compilation en C ++. En fait, un système de modules approprié a été envisagé pour C ++ 11, mais a chuté par manque de temps. Je suppose que cela reviendra, cependant.
sbi

Je suppose que cela reviendra, cependant. En fait WG21 (le groupe de travail ISO C ++) a un groupe d'étude uniquement dans le but d'évaluer / développer le concept de "modules": SG2 "Modules". Dommage que son statut actuel soit dormant .
Max Truxa

Réponses:


46

La réponse suivante qui ne répond pas à mes exigences: "Parce que James Gosling ne voulait pas."

C'est pourtant la bonne réponse. L'équipe de conception linguistique (Gosling, Sheridan, Naughton, plus tard Bill Joy, Ken Arnold, etc.) a décidé que les en- têtes causaient plus de problèmes qu'ils n'en résolvaient . Ils les ont donc conçus et ont démontré qu'ils pouvaient créer un langage parfaitement utile sans en avoir besoin.

De la section 2.2.1 du livre blanc de Java Language Environment :

Le code source écrit en Java est simple. Il n'y a pas de préprocesseur, pas de # définition et capacités associées, pas de typedef, et en l'absence de ces fonctionnalités, plus besoin de fichiers d'en-tête. Au lieu des fichiers d'en-tête, les fichiers source du langage Java fournissent les définitions d'autres classes et leurs méthodes.

Définitions redondantes, synchronisation des fichiers, définitions conflictuelles, définitions masquées - rien de tout cela ne se produit en Java, car vous n'avez pas d'en-tête. Si vous voulez voir une définition de classe nue, vous pouvez en générer une directement à partir d'un fichier .java - par exemple, la plupart des IDE vous montreront la structure d'une classe dans une barre latérale, ce qui revient au même.


6
Merci pour votre réponse, les en-têtes ont causé plus de problèmes à cause de cela: définitions redondantes, synchronisation des fichiers, définitions conflictuelles, définitions cachées. Est-ce pour cela que cela n'a pas été autorisé?
Etienne Noël

2
Notez qu'il y a beaucoup de discussions sur les prochaines réunions du Comité C ++ car ils envisageront un nouveau système "Module" qui serait un système plus simple et plus efficace que l'inclusion (avec quelques similitudes avec les packages java, C # etc.) mais toujours rétro -compatible avec comprend. Cela signifie qu'un meilleur système de compilation peut, au moins en théorie, être utilisé pour rendre la compilation C ++ meilleure / plus efficace. Gosling avait raison, je suppose, et C ++ doit de toute façon trouver un moyen de réparer le système d'inclusion.
Klaim

5
Ce n'est pas parfaitement utilisable. Les systèmes de génération Java ne peuvent pas déterminer quels fichiers doivent être recompilés après un changement de code. Un IDE déterminera quels fichiers nécessitent un changement de code, mais pas ceux qui nécessitent une recompilation. Si une signature de méthode change, mais que le changement est compatible avec l'ancien code (par exemple, changer un type d'argument de float en double), une construction propre est requise pour empêcher MethodNotFoundException.
Kevin Cline

1
@kevin: Cependant, il est généralement possible de tout reconstruire sans trop de frais. Contrairement à C ++ (mais comme presque tous les autres langages compilés sur terre), Java ne prend pas si longtemps pour compiler cette compilation partielle est une optimisation très utile de votre flux de travail de développement.
Donal Fellows

1
@Donal: Il est vrai que Java se compile assez rapidement, mais je déteste deviner si je dois ou non faire une recompilation complète. Les versions devraient simplement fonctionner, à chaque fois.
kevin cline

16

Il n'y a pas vraiment besoin en C ++ d'avoir les définitions et déclarations de classe dans des fichiers séparés. Cela signifie simplement que vous pourriez, au moins dans les jours C, effectuer l'analyse en un seul balayage de haut en bas du code. Sur les machines sans stockage à accès aléatoire, c'était un gros problème!

Avoir des en-têtes vous a également permis de publier l'interface dans votre bibliothèque de code en fournissant l'en-tête sans avoir à révéler le code source. Malheureusement, en C ++, vous devez également révéler les données privées des membres, ce qui a conduit à des solutions comme l'horreur de pimpl .

Il y a eu des tentatives pour créer un environnement C ++ où tout était stocké dans une structure de type base de données et il n'y a pas de fichiers mais cela n'a pas fonctionné.


Je le sais, mais au moins vous pouvez le faire en C ++ et non en Java; c'était ma principale enquête. Merci d'avoir répondu.
Etienne Noël

14

En raison du principe DRY . En Java, les informations nécessaires pour utiliser des classes dans un package (ou classe) sont contenues dans le fichier .class. La création de fichiers d'en-tête séparés contenant les mêmes informations impliquerait de les répéter à deux endroits.


malheureusement, vous voulez souvent le répéter - pensez aux fichiers wsdl, aux fichiers idl, etc. L'un décrit l'interface que vous pouvez utiliser et un autre fichier contient l'implémentation. Les en-têtes C ++ sont des définitions d'interface (médiocres).
gbjbaanb

6

Dans chaque langue - il y a deux étapes pour créer du code binaire final - la compilation et la liaison (bien sûr, il y a un chargement mais cela n'a pas beaucoup d'impact ici). Au moment de la compilation, il suffit de placer les crochets (la spécification des fonctions qui seront appelées) à l'endroit approprié. L'éditeur de liens les rejoint réellement lorsque le code réel est disponible. Jusqu'à présent, il n'y a aucune différence entre C ++ et Java.

Il existe cependant un besoin pour C ++ d'avoir une déclaration et une définition distinctes. Si vous conservez l'implémentation dans l'en-tête et si le fichier d'en-tête change, le code qui lui est lié doit être recompilé. Là où, comme si la définition se trouve dans un fichier séparé, le code n'a besoin que d'être re-lié.

Comprenez que C ++ a une option pour avoir une liaison statique, ce qui implique que le code objet est fixé avec l'application appelante. Veuillez noter qu'en C et C ++, il n'est pas invalide d'avoir la programmation dans le fichier d'en-tête ou même de faire #include. cela signifie seulement que vous devez vous soucier de la façon dont la liaison se produit avec ces fichiers objets.

La situation à Java est très différente. Chaque fichier de classe est compilé avec le fichier .class. En effet, la nécessité d'une compilation de fonction de classe appelant qui est servie comme une section d'en-tête dans le fichier .class. Cependant, en Java, la liaison finale se fait uniquement à l'intérieur du Runtime (la machine virtuelle) uniquement avec cette spécification du code d'octet du fichier de classe.

Voir ceci et cela


4

En effet, les interfaces et les inclus sont les en-têtes; les définitions sont donc identiques aux binaires et ne peuvent pas être désynchronisées. C'est l'une des meilleures décisions de conception en Java, mais c'est un inconvénient mineur qu'il n'y a aucun moyen de regrouper ces déclarations pour la compacité et la cohérence.


1

Une bonne raison d'avoir des inclusions est de séparer le code que vous voudrez peut-être réutiliser (comme les définitions courantes) du code spécifique à un projet donné. Java veut que vous spécifiiez une seule classe ou interface par fichier et cela réduit principalement le besoin d'en-têtes inclus - car vous aurez déjà les parties partagées dans leurs propres fichiers.

En outre, les compilateurs et les systèmes de génération peuvent vouloir mettre en cache les en-têtes précompilés pour éviter de les analyser plus d'une fois.


1
Je suppose que vous pouvez stocker les interfaces dans un projet partagé, puis les implémenter dans des projets indépendants
Alexander Mills
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.