JVM prend en charge de nombreux langages autres que Java comme Groovy,Clojure,Scala
etc., qui sont des langages fonctionnels contrairement à Java (je fais référence à Java avant la version 8 où Lambda's
ils ne sont pas pris en charge) qui ne prend pas en charge les capacités fonctionnelles. À un niveau élevé, ce qui rend la JVM si polyvalente qu'elle peut prendre en charge les langages orientés objet et fonctionnels?
18
Réponses:
Par rapport aux autres VM, la JVM n'est en fait pas particulièrement polyvalente . Il prend directement en charge OO de type statique. Pour tout le reste, vous devez voir quelles parties vous pouvez utiliser et comment vous pouvez construire tout ce dont votre langue a besoin par-dessus ces parties.
Par exemple, jusqu'à ce que Java 7 introduise le
invokedynamic
bytecode, il était très difficile d'implémenter un langage OO typé dynamiquement sur la JVM - vous deviez utiliser des solutions de contournement complexes qui étaient mauvaises pour les performances et entraînaient des traces de pile horriblement gonflées.Et pourtant, un tas de langages dynamiques (Groovy, Jython, JRuby entre autres) ont été implémentés sur la JVM avant cela.
Non pas parce que la JVM est si polyvalente, mais parce qu'elle est si répandue et parce qu'elle a des implémentations très matures, bien prises en charge et très performantes.
Et, peut-être encore plus important, car il existe une énorme quantité de code Java qui fait à peu près n'importe quoi, et si votre langage s'exécute sur la JVM, vous pouvez facilement offrir des fonctionnalités pour l'intégrer à ce code. Fondamentalement, l'exécution de votre langage sur la JVM est la version du 21e siècle de l'interopérabilité avec C.
la source
La JVM a été écrite pour agir essentiellement comme un CPU, il y a un ensemble d'instructions, un peu comme un assemblage, que la VM exécute appelé bytecodes. Si vous pouvez écrire un compilateur qui génère un ensemble valide de bytecodes, la JVM peut les exécuter.
Wikipedia a une liste des bytecodes:
http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
ainsi qu'une explication de la façon dont la JVM charge les codes d'octets:
http://en.wikipedia.org/wiki/Java_virtual_machine
En utilisant les bytecodes de style d'invocation, un langage fonctionnel peut exécuter du code, quelle que soit la source. De plus, avec l'ajout de invokevirtual, les implémentations de langage comme jruby ont donné une certaine flexibilité dans leur fonctionnement.
la source
J'ajouterai que la JVM prend en charge un modèle de mémoire ( JMM ) bien défini et assez décent, ce qui signifie une bonne prise en charge d'un comportement de threading cohérent (bien que de bas niveau). Il dispose également d'un puissant compilateur Just In Time (plus utile pour les langages dynamiques grâce à MethodHandles et invokedynamic).
Le dernier mais non le moindre est le sous-système Garbage Collection de la JVM qui (avec le bon réglage) gère la mémoire pour vous quelle que soit la langue du dessus.
la source
someField = new int[]{42};
les seules façons de s'assurer que tout thread qui voit le nouveau tableau verra la valeur 42 doivent soit faire le champfinal
ouvolatile
. Si le champ est généré paresseusement mais accédé fréquemment, le fairefinal
ne fonctionnera pas et le rendrevolatile
peut imposer une pénalité de synchronisation inutile à chaque fois qu'il est accédé. Même dans le modèle .NET le plus lâche ...L'élément clé est la séparation de la compilation de la phase d'exécution. Par cela, il est possible d'écrire d'autres compilateurs compilant d'autres langues en bytecode.
Le bytecode agit comme le code machine d'un CPU - vous avez toutes les petites opérations nécessaires pour exécuter un programme - vous pouvez obtenir une variable, faire des calculs dessus, avoir des opérations conditionnelles, etc.
Java n'est pas non plus spécial. En Java, l'existence de plusieurs langages n'était même pas un objectif de conception, contrairement aux autres machines virtuelles. Pour .Net CIL de Microsoft, la capacité d'exécuter plusieurs langues (C #, VB.Net, ...) était un élément clé de la conception, ainsi que le ParrotVM du projet Perl6 visant à être une machine virtuelle générique.
Pour le plaisir, j'ai créé une fois une preuve que même le moteur Zend de PHP le permettrait.
Et franchement, ce n'est pas quelque chose de nouveau - même sur du vrai matériel, vous pouvez exécuter plusieurs langues - c'est-à-dire C ou Fortran.
La différence par rapport à cette séparation de la compilation et de l'exécution sont les interprètes clssic, comme certaines formes de Basic, les scripts shell, etc. ils fonctionnent souvent de manière à exécuter le code plus ou moins ligne par ligne sans le mettre sous une forme immédiate entre.
la source
La machine virtuelle Java est la première machine virtuelle que je connaisse qui combine la récupération de place, les performances et un modèle sandbox fonctionnel. L'émergence de nombreux langages pour prendre en charge la JVM n'est probablement pas tant le résultat de sa "polyvalence", mais plutôt le fait que le langage Java manque de fonctionnalités importantes que les gens veulent dans un langage de programmation. Par exemple, alors que la plupart des langages machine ont seulement une demi-douzaine de types de données (par exemple, octet, demi-mot, mot, double mot, flottant simple précision et flottant double précision), la grande majorité des langages de programmation permettent au code d'utiliser un nombre arbitraire de types de données définis par l'utilisateur. La machine virtuelle Java reconnaît quelques types primitifs similaires à ceux d'une machine typique, plus un autre type: la référence d'objet promiscuous. Le langage Java reconnaît également ces primitives, et références aux objets promiscuité. Bien qu'une variable puisse être contrainte de ne pas contenir de références à tout ce qui n'est pas une classe particulière, le langage ne fait aucune distinction entre les types de champs de type suivants
List<String>
qui pourraient être détenus parMyThing
classe d' instanceMyClass
:Une référence à quelque chose de code sait être une implémentation immuable de
List<String>
Une référence à une instance d'un type de liste mutable qui ne sera jamais exposée à quoi que ce soit qui pourrait la muter.
Une référence à une liste mutable à laquelle, sauf lors de l'exécution des
MyThings
méthodes de, aucune autre référence ne pourrait exister nulle part dans l'univers.Une référence à une liste mutable qui appartient à un autre objet , que cet autre objet aimerait
MyThing
utiliser d'une manière ou d'une autre.Une référence à une liste mutable qui
MyThing
possède, mais qu'elle a également exposée à d'autres objets afin qu'ils puissent faire quelque chose avec elle.Même si tous ces champs peuvent avoir un type
List<String>
, ils contiennent des choses très différentes. Un langage expressif pourrait permettre une distinction entre ces significations, mais Java ne le permet pas. Puisqu'un langage peut attacher du sens à de telles choses (au moins en dehors des contextes génériques) et s'exécuter sur la JVM, cela laisse beaucoup de place aux langages ciblés par la JVM pour exprimer des concepts que Java ne peut pas.la source