Как виртуальная машина Java выполняет код, написанный на других языках?

12

Начиная с Java 1.6, JVM может работать с множеством языков программирования, а не только с Java. Я концептуально понимаю, как Java запускается на Java VM, но не понимаю, как другие языки могут работать на ней. Для меня все это выглядит как черная магия. У вас есть какие-нибудь статьи, на которые я могу указать, чтобы я мог лучше понять, как все это сочетается?

Pomario
источник
2
Точно так же, как ваш процессор Intel / AMD / Solaris (??) может выполнять «любой язык» (хотя вы на самом деле не запускаете языки, а просто работаете здесь), который может быть скомпилирован в его собственный код сборки.
Апурв Хурасия
13
Дело в том, что JVM не запускает Java. Он работает на другом (хотя и связанном и намеренно легком для создания компиляторами Java) языке более низкого уровня.
Это правда. Но JVM начала использовать другие языки с версии 6; Вы не могли (или никто не делал) запустить Python или Groovy на нем в версии 1.4.2. Почему это так? Что изменилось?
Помарио
@delnan Или, скорее, «более низкоуровневая модель исполнения, которую javac-программа знает, как создавать из Java-кода».
Апур Хурасия
9
@Pomario Jython существует уже некоторое время. И эта страница, кажется, предполагает, что Jython-скрипты могут работать на 1.4.2.
Апурв Хурасия

Ответы:

23

Ключ - родной язык JVM: байт-код Java. Любой язык может быть скомпилирован в байт-код, который понимает JVM - все, что вам нужно для этого - это компилятор, генерирующий байт-код. С тех пор нет никакой разницы с точки зрения JVM. Настолько, что вы можете взять скомпилированный файл классов Scala, Clojure, Jython и т. Д. И декомпилировать его (используя, например, JAD ) в обычный исходный код Java.

Вы можете найти более подробную информацию об этом в следующих статьях / темах:

Мне неизвестны какие-либо фундаментальные изменения в Java 5 или 6 JVM, которые позволили бы (или скомпилированы из) других языков работать на нем. В моем понимании, JVM 1.4 была более или менее способна в этом отношении, как JVM 6 (хотя могут быть различия; я не эксперт по JVM). Просто люди начали разрабатывать другие языки и / или компиляторы байт-кода в первой половине десятилетия, и результаты начали появляться (и стали более широко известны) примерно в 2006 году, когда была опубликована Java 6.

Однако все эти версии JVM имеют некоторые ограничения: JVM статически типизирован по своей природе, и вплоть до выпуска 7 не поддерживал динамические языки. Это изменилось с введением invokedynamicновой инструкции байт-кода, которая позволяет вызывать метод, полагаясь на динамическую проверку типов.

Петер Тёрёк
источник
8
Не совсем верно, что JVM не «поддерживала» динамические языки. Они просто должны были использовать обходные пути, которые имели серьезные недостатки.
Майкл Боргвардт
3
@MichaelBorgwardt, можем ли мы согласиться с тем, что JVM pre v7 допускает динамические языки (в некоторой степени)? :-)
Петер Тёрёк
1
Это хороший способ выразиться :)
Майкл Боргвардт
3

Виртуальная машина, как и JVM, - это программа, которая принимает в качестве входных данных, обычно файлы, набор простых инструкций (которые обычно легко преобразовать в настоящие инструкции ЦП) и фактически компилирует и запускает их как собственные инструкции ЦП (обычно с использованием компилятор по требованию, такой как HotSpot или JIT).

По сути это слой абстракции. Обычно гораздо проще портировать реализации набора команд VM на разные архитектуры процессоров из-за нескольких сходств (например, на основе стека). Кроме того, гораздо проще портировать разные языки программирования на команды виртуальных машин, поскольку они больше ориентированы на современные языки программирования, чем на примитивные инструкции процессора. Многие виртуальные машины, такие как JVM и CLR (.NET), содержат инструкции для вызова виртуальных методов и создания экземпляров объектов.

Итак, давайте возьмем язык для примера. Назовите это MyLanguage. Поскольку это язык программирования, он в конечном итоге сводится к набору некоторых инструкций архитектуры процессора. Это означает, что при наличии совместимого гибкого набора команд виртуальной машины также возможно скомпилировать MyLanguage до набора инструкций этой виртуальной машины.

Всегда есть вопрос эффективности, так как вам, возможно, придется взломать некоторые обходные пути в наборах команд виртуальных машин, которые вам не придется делать изначально, но это все же возможно.

Ям Маркович
источник
3

JVM - это вычислительная машина, полная Тьюринга (за исключением ограниченной памяти), и любая машина, полная Тьюринга (физическая или виртуальная), может выполнять любой язык программирования (за исключением ограничений памяти, производительности и физического ввода-вывода).

hotpaw2
источник
Хм .... зачем нам тогда компиляторы? ;-)
Петер Тёрёк
Сами компиляторы и интерпретаторы могут работать на машинах Тьюринга (возможно, медленно). Возможно, некоторые этапы предварительной компиляции / перевода могут улучшить производительность запуска определенной программы на каком-то конкретном языке?
hotpaw2
1
Я хотел сказать, что ваше утверждение «любая машина, полная Тьюринга (физическая или виртуальная), может выполнять любой язык программирования» буквально означает, что процессор x86 моего ноутбука может напрямую выполнять этот замечательный исходный файл Java, над которым я сейчас работаю. Или машинный код для процессоров PowerPC. Без компиляторов - процессоры не содержат компиляторов, верно? :-)
Петер Тёрёк
Ваша «машина» - это больше, чем просто процессор.
hotpaw2
1
@ PéterTörök Я понимаю вашу точку зрения. Он не уточнил виртуальные машины, как мы. Но я думаю, что его ответ все еще кратко отвечает на вопрос ОП. JVM может «запускать» другие языки программирования, потому что она может «запускать» любой язык программирования, потому что она завершена по Тьюрингу. Может быть, не сложным, но все же кратким и обоснованным. :)
Ям Маркович
2

На мгновение представьте, что JVM - это процессор с собственным набором инструкций, например, x86. Процессор может выполнить, скажем, C-код, который был скомпилирован в его машинный язык. Применяя ту же аналогию к JVM, другие языки могут быть выполнены на JVM точно так же, как на других процессорах, если эти языки скомпилированы в машинные инструкции JVM. Затем JVM может выполнить эти инструкции для языка X.

Cobie
источник
Ваша аналогия хорошая
Коби