Je me demande comment Java est plus portable que C, C++ et .NET et tout autre langage. J'ai souvent lu que Java était portable en raison de l'interpréteur et de la machine virtuelle Java, mais la machine virtuelle cache simplement les différences architecturales dans le matériel, n'est-ce pas? Nous aurions toujours besoin de différentes machines virtuelles pour différentes architectures de machine. Qu'est-ce que j'oublie ici? Donc, si quelqu'un écrit une couche d'abstraction pour C pour les architectures les plus courantes, disons le CVM, alors tout programme C s'exécutera sur ces architectures une fois que le CVM sera installé, n'est-ce pas?
Quelle est exactement cette portabilité? Peut-on appeler .NET portable?
La transférabilité n'est pas une chose en noir et blanc, oui ou non. La portabilité est la facilité avec laquelle je peux prendre un programme et l'exécuter sur toutes les plates-formes qui comptent pour vous.
Il y a quelques choses qui affectent ceci. L'un est la langue elle-même. La spécification du langage Java laisse généralement beaucoup moins à "l'implémentation". Par exemple, "i = i ++" n'est pas défini en C et C++, mais a une signification définie en Java. Plus concrètement, les types tels que "int" ont une taille spécifique en Java (par exemple: int est toujours 32 bits), tandis qu'en C et C++, la taille varie en fonction de la plate-forme et du compilateur. Ces différences à elles seules ne vous empêchent pas d'écrire du code portable en C et C++, mais vous devez être beaucoup plus diligent.
Un autre est les bibliothèques. Java a un tas de bibliothèques standard que C et C++ ne possèdent pas. Par exemple, bibliothèques de threading, de mise en réseau et d'interface graphique. Des bibliothèques de ce type existent pour C et C++, mais elles ne font pas partie du standard et les bibliothèques correspondantes disponibles peuvent varier considérablement d'une plate-forme à l'autre.
Enfin, il y a toute la question de savoir si vous pouvez simplement prendre un exécutable et le déposer sur une autre plate-forme et le faire fonctionner là-bas. Cela fonctionne généralement avec Java, en supposant qu'il existe une machine virtuelle Java pour la plate-forme cible. (et il existe des machines virtuelles pour de nombreuses/la plupart des plates-formes qui intéressent) Cela n’est généralement pas vrai avec C et C++. Vous allez généralement à moins avoir besoin d’une recompilation, et cela en supposant que vous ayez déjà pris en charge les deux points précédents.
Oui, s'il existait un "CVM" pour plusieurs plates-formes, cela rendrait C et C++ plus portables - en quelque sorte. Vous aurez toujours besoin d’écrire votre code C de manière portable (par exemple, en supposant que rien n’est plus gros que ce que dit le standard), ou bien vous écrivez au CVM (en supposant qu’il ait pris une décision uniforme toutes ces choses sur toutes les plateformes cibles). Vous devrez également renoncer à l'utilisation de bibliothèques non standard (pas de réseau, de thread ou d'interface graphique) ou écrire dans les bibliothèques spécifiques à CVM à ces fins. Nous ne parlons donc pas vraiment de rendre le C et le C++ plus portables, mais d’un CVM-C/C++ spécial portable.
Encore une fois, la portabilité n’est pas une chose en noir et blanc. Même avec Java, il peut toujours y avoir des incompatibilités. Les bibliothèques d'interface graphique (en particulier AWT) étaient connues pour avoir un comportement incohérent, et tout ce qui implique des threads peut se comporter différemment si vous êtes négligé. En général, cependant, il est beaucoup plus facile de prendre un programme Java non trivial écrit sur une plate-forme et de l'exécuter sur une autre que de faire de même avec un programme écrit en C ou C++.
Comme d'autres l'ont déjà dit, la portabilité est un concept quelque peu flou. D'un certain point de vue, C est en faitplusportable que Java. C fait très peu d'hypothèses sur le matériel sous-jacent. Cela ne suppose même pas qu'il y ait 8 bits dans un octet, ou que Les nombres négatifs doivent être représentés en utilisant le complément à 2. Théoriquement, tant que vous avez une machine Von Neumann et un compilateur, vous pouvez jouer avec C.
En fait, un programme "Hello world" écrit en C fonctionnera sur beaucoup plus de plates-formes qu’un programme "Hello world" écrit en Java. Vous pourriez probablement utiliser le même programme "hello world" sur un PDP-11 et un iPhone.
Cependant, la réalité est que la plupart des programmes du monde réelfont beaucoup plus que la sortie "Hello world". Java a la réputation d'être plus portable que le C, car en pratique, cela demande beaucoup plus d'effort de porter des programmes C du monde réel sur des plates-formes différentes de celles des programmes Java du monde réel.
En effet, le langage C est en réalité ANSI-C, langage extrêmement nuancé et extrêmement polyvalent. Il ne prend pas en charge la programmation réseau, le threading ou le développement d'interface graphique. Par conséquent, dès que vous écrivez un programme qui inclut l’un de ces éléments, vous devez vous rabattre sur un fichier extensionto C) moins portable que Win32, POSIX ou autre.
Mais avec Java, les outils de programmation réseau, de threading et d'interface graphique sont définis par le langage et intégrés à chaque implémentation VM.
Cela dit, je pense que beaucoup de programmeurs sous-estimentles progrès réalisés par le C/C++ moderne en matière de portabilité de nos jours. POSIX va un long chemin en fournissant un threading multi-plateforme, et en ce qui concerne C++, Boost fournit des bibliothèques de réseautage et de threads qui sont fondamentalement aussi portables que tout ce qui existe en Java, avec quelques particularités propres à la plate-forme, mais Java également.
Java repose essentiellement sur chaque plate-forme ayant une implémentation VM interprétant de manière prévisible le code octet, et C/C++ sur des bibliothèques incorporant du code spécifique à la plate-forme à l'aide du préprocesseur (#ifdef
s). Les deux stratégies permettent le threading multi-plateforme, la mise en réseau et le développement d'interface graphique. C'est simplement que Java a progressé plus rapidement que C/C++ en ce qui concerne la portabilité. Dès le premier jour, les spécifications de langage Java prévoyaient le développement de threads, de réseaux et d'interfaces graphiques, alors que la bibliothèque de réseaux Boost n'est disponible que vers 2005, et ce n'est qu'en 2011 avec C++ 11 que le threading portable standard a été inclus en C++.
Lorsque vous écrivez un programme Java, celui-ci s’exécute sur toutes les plates-formes dotées de la machine virtuelle Java (Windows, Linux, MacOS, etc.).
Si vous écrivez un programme C++, vous devrez le compiler spécifiquement pour chaque plate-forme.
Maintenant, on dit que la devise de Java "écrire une fois, courir partout" est un mythe. Ce n'est pas tout à fait vrai pour les applications de bureau, qui nécessitent une interaction avec de nombreuses ressources natives, mais chaque application JavaEE peut être exécutée sur n'importe quelle plate-forme. Actuellement, je travaille sur Windows et d’autres collègues travaillent sur Linux - sans aucun problème.
(Une autre chose liée à la portabilité est JavaEE (Enterprise Edition). On dit que les applications écrites avec les technologies JavaEE s'exécutent sur tout serveur d'applications certifié JavaEE. Cependant, ceci n'est vrai qu'au moins jusqu'à JavaEE6. ( voir ici ))
La portabilité est une mesure de la quantité d'effort nécessaire pour faire en sorte qu'un programme s'exécute dans un autre environnement que celui d'origine.
Vous pouvez maintenant décider si une machine virtuelle sur Linux est dans un environnement différent de celui de Windows (je dirais que oui), mais il n'en reste pas moins que dans de nombreux cas, aucun effort n'est requis si vous évitez quelques pièges.
Le CVM dont vous parlez est bien ce que les bibliothèques POSIX et les bibliothèques d’exécution essaient de fournir, mais il existe de grandes différences d’implémentation qui rendent les obstacles difficiles à franchir. Certes, dans le cas de Microsoft et d’Apple, il en va probablement ainsi intentionnellement pour empêcher les développeurs de commercialiser des produits sur des plates-formes concurrentes.
Sur le plan .net, si vous pouvez vous en tenir à ce que mono fournit, une implémentation .Net open source, vous bénéficierez à peu près du même type de portabilité que Java, mais étant donné que mono est nettement en retard par rapport aux versions Windows, ce choix n’est pas populaire. . Je ne sais pas à quel point c'est populaire pour le développement basé sur serveur où je peux imaginer que c'est moins un problème.
Java est portable du point de vue du développeur: le code écrit en Java peut être exécuté dans n'importe quel environnement sans qu'il soit nécessaire de recompiler. C n’est pas portable car, dans de nombreux cas, il est non seulement lié à un système d’exploitation spécifique, mais également à une architecture matérielle spécifique une fois celle-ci compilée. La même chose est vraie pour C++. .Net est plus portable que C/C++, car il repose également sur une machine virtuelle et n'est donc pas lié à une architecture matérielle spécifique au moment de la compilation, mais il est limité aux machines Windows (officiellement).
Vous avez raison, la machine virtuelle Java est spécifique à la plate-forme (ce doit être!), Mais lorsque vous dites que Java est portable, vous en parlez d'un point de vue développeur et les développeurs Java standard n'écrivent pas la machine virtuelle Java, ils l'utilisent: - ).
Edit @ Raze2Dust Pour répondre à votre question. Oui vous pourriez. En fait, vous pourriez rendre Java spécifique à la plate-forme en écrivant un compilateur qui générerait du code machine plutôt que du bytecode. Mais comme le suggèrent certains autres commentaires, pourquoi voudriez-vous faire cela? Vous devez créer un interpréteur qui mappe le code compilé aux opérations de la même manière que la machine virtuelle Java. En résumé, vous pouvez le faire, mais pourquoi le feriez-vous?
Java fournittroisdes types distincts de portabilité:
Portabilité du code source: Un programme Java donné doit produire des résultats identiques, quel que soit le processeur, le système d'exploitation ou le compilateur Java sous-jacent.
Portabilité de l'architecture de la CPU: les compilateurs Java actuels produisent un code objet (appelé code octet) pour une CPU qui n'existe pas encore. Pour chaque CPU réel sur lequel les programmes Java doivent être exécutés, un interpréteur Java ou une machine virtuelle, "exécute" le code-J. Ce processeur non existant permet au même code d'objet de s'exécuter sur tout processeur pour lequel il existe un interpréteur Java.
Portabilité du système d'exploitation/de l'interface graphique: Java résout ce problème en fournissant un ensemble de fonctions de bibliothèque (contenues dans des bibliothèques fournies par Java, telles que awt, util et lang) qui communiquent avec un système d'exploitation et une interface graphique imaginaires. Tout comme la JVM présente un processeur virtuel, les bibliothèques Java présentent un système d’exploitation/interface graphique virtuel. Chaque implémentation Java fournit des bibliothèques implémentant cet OS/GUI virtuel. Les programmes Java qui utilisent ces bibliothèques pour fournir assez facilement les fonctionnalités de système d'exploitation et d'interface graphique requises.
Voir ce link
Vous demandez si on pourrait écrire une "VM C". Pas exactement. Le terme "Java" est un terme générique utilisé par Sun pour désigner beaucoup de choses, notamment le langage de programmation et la machine virtuelle. "C" n'est qu'un langage de programmation: il appartient au compilateur, ainsi qu'à l'OS et à la CPU de choisir le format que devrait avoir le fichier binaire obtenu.
On dit parfois que C est portable parce que il ne spécifie pas le temps d'exécution. Les personnes qui ont écrit votre compilateur ont été en mesure de choisir des éléments pertinents pour cette plate-forme. L'inconvénient est que C est suffisamment bas et que les plates-formes sont suffisamment différentes pour qu'il soit courant que les programmes C fonctionnent correctement sur un système et pas du tout sur un autre.
Si vous combinez le langage C avec une ABI spécifique, vous pouvez définir un VM correspondant à celui-ci, analogue à la JVM. Il y a quelques choses comme ça déjà, par exemple:
Toutes ces machines virtuelles C sont en fait une vraie machine - personne, AFAIK, n’a jamais réalisé une C VM purement virtuelle. Cela n’est pas surprenant, car C a été conçu pour fonctionner efficacement sur du matériel, vous pouvez donc aussi bien le faire fonctionner normalement sur un système. Comme HP l'a montré, vous pouvez toujours créer un JIT pour exécuter le code plus efficacement, même sur la même plate-forme.
La portabilité ou comme écrit dans Wikipedia, La portabilité du logiciel est la possibilité de réutiliser le même logiciel (code) dans plusieurs environnements (OS). La JVM Java est une JVM qui peut être exécutée sous n’importe quel système d’exploitation pour lequel elle a été conçue: Windows, Linux, Mac OS, etc.
Sur .NET, il est possible de porter votre logiciel sur différentes plates-formes. De Wikipedia :
La conception du .NET Framework Lui permet d'être théoriquement agnostique sur la plate-forme Et donc compatible entre plates-formes . C'est-à-dire qu'un programme écrit Pour utiliser le cadre devrait exécuter Sans changement sur aucun type de système Pour lequel le cadre est Mis en œuvre.
Et comme Microsoft n’a jamais mis en oeuvre le framework .NET en dehors de Windows et que, étant donné que .NET n’était pas agnostique sur sa plate-forme, Mono a rendu possible l’exécution d’applications .NET et la compilation de code pour Linux.
Pour les langages tels que C++, Pascal, etc., vous devrez vous connecter à chaque système d'exploitation et le construire sur cette plate-forme pour pouvoir l'exécuter sur cette plate-forme. Le fichier EXE de Windows n’est pas identique au .so
de Linux (le code machine), car ils utilisent tous les deux des bibliothèques différentes pour communiquer avec le noyau et chaque système d’exploitation possède son propre noyau.
Vous avez besoin de la machine virtuelle Java pour différentes architectures, mais bien entendu, vos programmes Java exécutent sur cette machine virtuelle Java . Donc, une fois que vous avez une machine virtuelle Java pour une architecture, vos programmes Java sont disponibles pour cette architecture.
Je peux donc écrire un programme Java, le compiler en bytecode Java (qui ne dépend pas de l'architecture), ce qui signifie que je peux l'exécuter sur n'importe quelle machine virtuelle sur n'importe quelle architecture. La JVM résume l'architecture sous-jacente et mon programme s'exécute sur une machine virtuelle.
L'idée est que le langage Java language est portable (ou plus précisément, le code d'octet compilé est portable). Vous avez raison de dire que chaque VM nécessite une implémentation spécifique pour un profil matériel donné. Cependant, une fois que cet effort a été fait, le bytecode all Java sera exécuté sur cette plate-forme. Vous écrivez le code Java/bytecode une fois et il s'exécute sur n'importe quelle machine virtuelle Java.
.NET est assez similaire, mais avec une importance beaucoup moins grande sur le principe. Le CLR est analogue à la machine virtuelle Java et possède son propre bytecode. Mono existe sur * nix, mais vous avez raison de dire que ce n'est pas "officiel".
WORE - Write Once Run Everywhere
En réalité, cela se limite aux plates-formes dotées d'une machine virtuelle, mais cela couvre la majorité des plates-formes sur lesquelles vous souhaitez déployer. Il se situe presque à mi-chemin entre un langage interprété et un langage compilé, ce qui permet de tirer parti des avantages des deux.