Pourquoi Java est-il considéré comme plus portable que d'autres langages comme C ++?

16

Qu'est-ce qui diffère entre «écrire un JRE spécifique pour chaque plate-forme» pour les développeurs Java et «écrire un compilateur C ++ pour chaque plate-forme» pour les développeurs C ++?

user967316
la source

Réponses:

33

Java est compilé une fois exécuté n'importe où. C ++ est écrit une fois compilé n'importe où.

Pubby
la source
3
Eh bien, vous n'avez évidemment pas beaucoup d'expérience avec le développement d'interface graphique. (En attente de Qt ...)
27
Quiconque prétend que C ++ est "écrire une fois compiler n'importe où" n'a jamais eu à porter un programme C ++ ...
BlueRaja - Danny Pflughoeft
7
Je suis d'accord avec BlueRaja. Porter un programme C ++ signifie bien plus que porter le compilateur. C ++ est le plus largement présent dans les environnements critiques où des choses comme la taille d'un int ou la mise en œuvre d'un système de fichiers peuvent faire une si grande différence. Le portage ne signifie PAS simplement une recompilation.
rahmu
8
@ Pubby8 non, les problèmes de portabilité proviennent également d'un code assez standard qui fait des hypothèses non transférables , comme des hypothèses sur l'endianité (qui vous dérange, vous pouvez également en souffrir en Java), l'alignement et la taille des types fondamentaux.
R. Martinho Fernandes
5
Écrivez une fois, déboguez partout.
bhagyas
25

«écrire un JRE spécifique pour chaque plate-forme» n'est pas quelque chose que vous faites à chaque fois. Le portage du JRE sur une nouvelle plateforme est quelque chose que vous devez faire une seule fois. Cette tâche est généralement effectuée par le principal mainteneur / développeurs du programme et / ou de la plate-forme. De nombreux facteurs peuvent entrer en jeu pour décider qui et comment le JRE sera porté. Entre autres choses, cela dépend de la licence sous laquelle il est publié (j'entends que Java est Open Source, donc je suppose que n'importe qui pourrait le faire). Anecdote drôle, Steve Jobs a fait une grosse affaire de ne pas vouloir s'occuper du portage de Java sur Mac , il y a environ un an.

Il ne s'agit pas de savoir comment ou qui portera le JRE, mais le fait qu'une fois qu'il est porté, chaque application Java devrait désormais théoriquement s'exécuter facilement sur la nouvelle machine. En ce sens, le JRE forme une couche d'abstraction, cachant complètement la machine, permettant un portage facile.

Cependant, la réalité n'est pas toujours aussi jolie. Je n'irai pas jusqu'à qualifier la portabilité de "mythe", mais c'est vrai que ce n'est pas si parfait. Par exemple, Java a un package appelé JNIqui permet d'envoyer des appels natifs, en contournant le JRE, empêchant ainsi la portabilité parfaite parfaite, ce que les fans de Java aiment appeler "Écrire une fois exécuté partout".

Comme mentionné dans les commentaires, l'approche de C ++ en matière de portabilité est différente. D'une part, c'est un langage compilé, et ces binaires sont presque toujours spécifiques à la plate-forme. Ainsi, les exécutables c ++ ne seront jamais portables (contrairement à Java). En revanche, le portage du compilateur peut parfois suffire. La communauté a découvert qu'en portant le compilateur ainsi que certaines bibliothèques de base du langage, les codes source (et non les binaires) pouvaient être portables.

Cependant, le C ++ est largement utilisé dans les systèmes critiques comme les compilateurs, les noyaux, les systèmes en temps réel, les systèmes embarqués, ... Il y a un aspect "bas niveau" du C ++ qui ne peut pas être négligé, quand on parle de portabilité.

rahmu
la source
4
La portabilité n'est pas un mythe. La portabilité parfaite est.
Malcolm
"C'est là que Java est très différent de C ++, où chaque application est" spécifique à la machine ", et ne peut pas être portée sans modifier le code." Ce n'est pas vrai, cela dépend des dépendances. Si vous utilisez uniquement la bibliothèque standard et les bibliothèques avec des sources portables sur vos cibles, vous codez une fois et compilez sur chaque cible. Si vous codez quelque chose qui peut être porté sans modifier le code en C ++, la seule chose que vous devrez peut-être modifier sera les scripts de construction. Ce n'est même pas vrai dans tous les cas.
Klaim
N'oublions pas que C ++ peut être utilisé à la fois comme un langage de haut niveau et un langage de bas niveau. Beaucoup de code C ++ est utilisé dans les programmes où un int 32 bits est très différent d'un int 64 bits. Le haut niveau sera toujours portable, bien sûr. Mais c'est loin d'être une généralisation C ++
rahmu
Je pense que vous avez peut-être mal compris ce que je dis: vous pouvez écrire du C ++ correct avec int ou tout type standard sans vous soucier des trucs de bas niveau. Jetez un œil aux bibliothèques boost, la plupart ne sont que du code de haut niveau, et cela est vrai pour de nombreux projets open source C ++. Vous "pouvez" passer au niveau inférieur, et si vous le faites, vous pouvez également éviter tout code spécifique jusqu'à ce que vous deviez utiliser une API spécifique à la plate-forme. Mais si vous n'en avez pas besoin, vous pouvez écrire du C ++ qui fonctionne partout. La dépendance à la plate-forme peut être évitée et se trouve souvent dans le code de la bibliothèque.
Klaim
Juste pour être sûr que je suis clair: je ne dis pas que tout le code C ++ est portable, je dis que tel quel, votre déclaration est fausse. Vous voudrez peut-être le corriger avec quelque chose comme: "C'est là que Java est très différent de C ++, où chaque application est" spécifique à la machine ", et ne peut pas être portée sans modifier le code ou, si le code est vraiment portable et la construction les scripts gèrent la nouvelle cible, sans au moins une compilation. "
Klaim
14

Ce n'est pas seulement la langue - ce sont les bibliothèques.

Java et C ++ fournissent des bibliothèques multiplateformes. Java fournit un ensemble plus riche.

Andy Thomas
la source
2
Java fournit un ensemble plus riche par défaut. Les mêmes bibliothèques peuvent être trouvées pour C ++, elles ne font tout simplement pas partie des bibliothèques standard et il vous suffit de décider lesquelles utiliser (ce qui n'est pas trivial surtout si elles ne sont pas installées).
Martin York
Comparer les bibliothèques standard de Java à l'univers des bibliothèques pour C ++ n'est pas vraiment une comparaison valide. Java fournit un ensemble plus riche, que vous compariez les bibliothèques standard de chacune ou que vous compariez l'univers des bibliothèques de chacune.
Andy Thomas
3
Certainement en désaccord avec cela. Tout ce qui est disponible dans la bibliothèque Java est déjà disponible pour une utilisation par C ++ dans certaines bibliothèques. J'aime le fait que Java a tout en un seul endroit, mais dire qu'il est plus riche n'est tout simplement pas vrai. Peut-être que l'adjectif que vous recherchez est "plus intégré"
Martin York
1
+1 reviendrait à voter. Je pense que les bibliothèques sont le plus grand facteur de portabilité. Si vous travaillez en C / C ++ et faites autre chose que du calcul pur, il y aura des bibliothèques (en particulier, des parties de la bibliothèque système) qui sont radicalement différentes entre Windows et Unix, et subtilement différentes entre les différentes saveurs d'Unix. Cela rend le portage difficile. Java n'a fondamentalement pas ce problème.
Tom Anderson
1
@Andy Thomas-Cramer: Je ne compare rien (vous semblez l'être). Je dis que votre déclaration est inexacte. Un des avantages de Java (et nous l'aimons tous pour cela) est toutes les bibliothèques standard en un seul endroit. Dire qu'ils sont plus riches n'est tout simplement pas exact.
Martin York, le
7

La différence est que Java fonctionnera sur n'importe quelle plate-forme sans recompilation. Avoir un compilateur C ++ pour chaque plate-forme n'est pas du tout le même.

Highland Mark
la source
6

Toutes les réponses commençant par "La différence est ...", ou quelque chose de très similaire, sont fondamentalement erronées (désolé, mais telle est la vie). Il y a vraiment deux différences distinctes entre les deux.

L'une (qui a été souvent mentionnée) est qu'un programme Java compilé peut (ou du moins devrait) s'exécuter sur n'importe quelle implémentation conforme de Java, donc même après avoir été compilé, vous pouvez toujours déplacer un programme Java d'une plate-forme à une autre sans recompiler . C ++ (au moins normalement) nécessite une recompilation pour chaque plate-forme cible.

L'autre est que Java (au moins tente de) s'assurer que tout Java correctement écrit sera portable. Au moins en théorie, vous ne devriez pas pouvoir écrire de code qui n'est pas portable.

C ++ vous permet de faire pas mal de choses qui ne sont pas portables. La norme C ++ contient des "avertissements" sur beaucoup de choses qui ne sont pas portables (par exemple, vous dire que vous obtiendrez un comportement défini par l'implémentation ou un comportement non défini), mais il n'essaie pas nécessairement de vous empêcher de les faire du tout . Par exemple, si vous souhaitez écrire un système d'exploitation pour du matériel utilisant un bus PCI, vous devrez probablement lire / écrire la mémoire de configuration PCI. Cela ne sera évidemment pas portable sur les systèmes sans bus PCI, mais si vous écrivez un système d'exploitation pour le matériel avec un bus PCI, c'est à peu près nécessaire. C ++ le permet même s'il n'est évidemment pas portable.

Jerry Coffin
la source
C ++ ne sait rien du bus PCI ni du matériel.
Nikko
bien sûr que non, ce sont des choses spécifiques à la plate-forme qui devront être incluses dans les bibliothèques spécifiques à la plate-forme. Tout comme Java peut avoir des bibliothèques spécifiques à la plate-forme si nécessaire.
jwenting
1
@Nikko: Il n'en sait rien, mais il vous permet d'utiliser ce que vous en savez.
Jerry Coffin
@jwenting: La différence est que vous pouvez écrire les bibliothèques spécifiques à la plate-forme en C ++, mais vous ne pouvez généralement pas les écrire en Java.
Jerry Coffin
6

Vous avez mal compris les lieux. Les programmes Java sont très portables, car la JVM fournit un comportement standard garanti identique. Les programmes C ++ ont un environnement moins standardisé plus proche du matériel réel, donc le programme doit être capable de gérer les différents détails spécifiques à la plate-forme - comme la taille d'un int, l'alignement des mots, etc., etc.

La JVM elle-même n'est pas très portable. C'est une tâche herculéenne de porter une JVM hautement performante sur une autre plate-forme ou architecture de CPU.


la source
+1 pour cette dernière phrase!
rahmu
2

La différence est que les programmes Java (ce n'est pas un acronyme) peuvent être distribués sous une forme qui peut être exécutée sur n'importe quel ordinateur sur lequel une machine virtuelle Java est installée, mais C ++ est normalement distribué en tant que code source, qui est très peu convivial pour l'utilisateur, ou en tant que groupe de différents binaires pour différentes plates-formes.

Colin
la source
Hein? Il existe des compilateurs C ++ qui ciblent la JVM et il existe des compilateurs Java qui ciblent le code natif. Pouvez-vous citer la section spécifique de la spécification du langage C ++ qui dit que les programmes C ++ doivent être distribués en tant que code source ou binaires spécifiques à la plate-forme?
Jörg W Mittag
Là, j'ai modifié ma réponse pour utiliser un langage moins définitif
Colin
2

L'une des raisons pour lesquelles Java est considéré comme portable est qu'il a des règles spécifiques sur la façon dont les expressions arithmétiques doivent être évaluées et interdit les implémentations de les évaluer de toute autre manière, même lorsque les évaluer de la manière prescrite nécessiterait un code plus lent que de les évaluer de manière plus précise. mode.

Par exemple, étant donné

long thing1(int x) {
  return (x+1)-1L;
}
double thing2(int x, float y) {
  return x/y;
}

Les valeurs de thing1(2147483647)et thing2(1123456700,11234567.0f)doivent être respectivement -2147483649L et 99,9999923706054688, même si les valeurs arithmétiquement correctes seraient 2147483647L et 100,0, et même si sur certaines plates-formes, le code pour générer des résultats numériquement incorrects serait plus lent que le code pour générer le code correct. résultats (sur certaines plates-formes 64 bits, forcer le comportement d'habillage après (x + 1) nécessiterait une instruction supplémentaire, et sur la plate-forme 8x87, forcer la valeur de 1123456700 à être arrondi à floatnécessiterait une instruction supplémentaire par rapport au simple chargement directement à un registre à précision étendue).

supercat
la source
1
Pour une fois, une nouvelle réponse à une vieille question qui ajoute en fait quelque chose de valeur: Java a des exigences arithmétiques très précises, et bien sûr les types de données primitifs ont des tailles et une sémantique spécifiques par rapport à C ++. Aucune autre réponse à ce jour n'en fait mention.
@Snowman: Comment aimez-vous les exemples particuliers choisis? Personnellement, si je concevais un langage, je n'aurais pas fait que les deux exemples retournent la valeur de Java sans l'utilisation de rétrécissements (int)pour la (x+1)sous - expression du premier exemple dans le premier exemple, au paramètre floatdu deuxième exemple x, mais évidemment je n'ai pas conçu le langage .
supercat
Je pense qu'ils ont du sens. L'important pour toute langue est d'avoir une sémantique bien définie. Peu importe que l'on soit d'accord avec une décision de conception de langage donnée, l'important est de pouvoir regarder le code et savoir comment il fonctionne. Java fait généralement cela, avec quelques cas de comportement indéfini.
1

La quantité de travail pour les outils de support est en effet similaire, la différence est ailleurs. Une fois qu'un programme C ++ a été compilé pour une plate-forme, vous devez le recompiler si vous souhaitez l'utiliser sur une plate-forme différente. Cependant, lorsqu'un programme java a été compilé, vous pouvez le déplacer vers n'importe quelle autre plate-forme avec un environnement d'exécution sans avoir à le recompiler.


la source
1

En répondant au titre "La portabilité est-elle un mythe?", Au lieu de "Qui est meilleur en portabilité, Java ou C ++", je dirai que la portabilité partielle est possible, mais la portabilité complète est un mythe.

Quelque chose que j'insiste à écrire, et cela s'applique à cette question, c'est que les développeurs ne travaillent plus uniquement avec des langages de programmation, mais avec des cadres de programmation complets.

Et ces cadres, incluent des bibliothèques, des bases de données, des interfaces graphiques.

Quel langage de programmation ou quel cadre de programmation est plus portable?

Eh bien, cela dépend de ce que votre application. essaie d'atteindre.

umlcat
la source
1

Le fait est que "vous" n'écrivez pas le JRE, vous écrivez le code Java qui s'exécute sur n'importe quel JRE. "Vous" écrivez le code C ++ qui peut nécessiter des modifications de votre part avant qu'il ne soit compilé sur une autre plate-forme.

James Anderson
la source
0

Beaucoup de gens oublient ou ne prennent pas en compte la réalité de Java quand ils disent que "c'est 100% portable" ou des phrases comme ça.

Presque toutes les grandes sociétés / éditeurs de logiciels avaient au moins une implémentation maison de Java avec un JRE associé dans un passé récent et certains le maintiennent toujours, Microsoft, IBM et Apple, par exemple, avaient tous leur propre version de Java reflétant leur ses propres idées et réflexions sur l’orientation de l’industrie et de ce langage.

Comment est-ce pour "portable"? Un JRE partout où vous vous tournez.

Et cela sans tenir compte de ce que faisait Sun / Oracle.

Un exemple sur la raison pour laquelle le code Java n'est pas vraiment loin du C et C ++ en termes de portabilité sont les GUI et les serveurs graphiques, Apple avait une implémentation non standard du cadre GUI pour son propre JRE, en conséquence, il y avait beaucoup de des maux de tête et un double travail pour tous ceux qui voulaient créer / porter une interface graphique à l'aide de Java pour les machines Apple et ils ont été essentiellement obligés de gérer Quartz (comment est-ce en termes de "levier" et de langages de haut niveau?).

Parfois, même les mots les plus utilisés ne reflètent pas vraiment le sens que les gens leur donnent habituellement. Pour moi, le terme "portabilité" dans le monde Java ressemble plus à "perspectives" au sens commun; en termes commerciaux et financiers, il y a de meilleures perspectives pour vous si vous adoptez Java plutôt que d'autres langages (au moins au moment où Java est né) car vous avez déjà beaucoup de travail d'un côté (vous obtenez un JRE sur n'importe quoi qui peut être considéré comme un "ordinateur") et votre base de code est susceptible d'être portable telle quelle, vous avez besoin de moins de ressources pour porter votre programme, c'est tout, que cette ressource soit de l'argent, du temps ou de la main-d'œuvre n'a pas d'importance, c'est moins seuil par rapport à d'autres technologies et c'est à cela que sert Java, il abaisse ce seuil.

Bien sûr, cela est vrai si vous acceptez les prémisses de Java, ce qui signifie une machine virtuelle avec garbage collection, ce qui signifie qu'elle consomme plus de ressources par rapport aux langues natives, si vous voulez vraiment tirer le maximum de votre CPU ou batterie de serveurs I ne pensez pas que vous pouvez adopter Java à moins que vous soyez vraiment à court de ressources ou que votre entreprise soit vraiment petite.

Je dois encore trouver une seule application Java non triviale qui ne contient qu'une seule version pour chaque ligne de code ou fonctionnalité (c'est-à-dire sans aucun élément spécifique à la plate-forme) et elle est 100% portable parmi tous les principaux JRE.

user2485710
la source