Як Java Virtual Machine виконує код, написаний іншими мовами?


12

Оскільки Java 1.6 JVM може виконувати безліч мов програмування, а не просто Java. Я концептуально розумію, як Java запускається на Java VM, але не так, як інші мови також можуть працювати на ній. Для мене це все схоже на чорну магію. Чи є у вас якісь статті, щоб мене вказували, щоб я міг краще зрозуміти, як це все підходить разом?


2
Так само, як ваш процесор Intel / AMD / Solaris (??) може виконувати "будь-яку мову" (хоча ви дійсно не використовуєте мови, а просто переходите з потоку тут), який можна скласти у свій початковий код складання.
Апоорв Хурасія

13
Справа в тому, що JVM не працює на Java. Він має чітку (хоч і пов’язану і навмисно просту для створення компіляторів Java) мову більш низького рівня.

Це правда. Але JVM почав працювати з іншими мовами з версії 6; ви не могли (або ніхто не робив) запускати пітон або 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, - це програма, яка приймає як введення, як правило, файли, набір простих інструкцій (які, як правило, легко конвертувати в реальні інструкції CPU), і насправді компілює та запускає їх як рідні інструкції процесора (як правило, використовуючи компілятор на вимогу, такий як HotSpot або JIT).

По суті це шар абстракції. Зазвичай набагато простіше перенести реалізацію набору інструкцій VM в різні архітектури процесорів через декілька подібностей (наприклад, на основі стека). Також набагато простіше переносити різні мови програмування на інструкції VM, оскільки він більше орієнтований на сучасні мови програмування, ніж на примітивні інструкції процесора. Багато віртуальних машин, таких як JVM та CLR (.NET), містять інструкції щодо виклику віртуальних методів та створення об'єктів.

Тож візьмемо для прикладу мову. Назвіть це MyLanguage. Оскільки це мова програмування, вона в кінцевому підсумку складається до набору деяких інструкцій архітектури процесора. Це означає, що, маючи набір сумісних, гнучких наборів інструкцій щодо віртуальної машини, можна також скласти MyLanguage до набору інструкцій цього віртуального комп'ютера.

Завжди виникає питання ефективності, оскільки вам може знадобитися зламати деякі шляхи вирішення в наборах інструкцій VM, які вам не доведеться робити на самому собі, але це все-таки можливо.


3

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


Ем .... навіщо нам тоді потрібні компілятори? ;-)
Петер Тьорк

Укладачі та перекладачі самі можуть працювати на машинах Тьюрінга (можливо, повільно). Можливо, деякі етапи попередньої компіляції / перекладу можуть покращити ефективність запуску певної програми якоюсь даною мовою?
hotpaw2

1
Моя думка полягала в тому, що ваше твердження "будь-яка машина Тьюрінга (фізична чи віртуальна) може виконати будь-яку мову програмування" буквально означає, що процесор x86 мого ноутбука може безпосередньо виконати цей чудовий вихідний файл Java, над яким я працюю зараз. Або машинний код для процесорів PowerPC. Без компіляторів - процесори не містять компіляторів, правда? :-)
Петер Тьорек

Ваша "машина" - це не просто CPU.
hotpaw2

1
@ PéterTörök Я бачу вашу думку. Він не детально розробляв VM, як ми. Але я думаю, що його відповідь все ще коротко відповідає на питання ОП. JVM може "запускати" інші мови програмування, тому що він може "запускати" будь-яку мову програмування, тому що це Тьюрінг завершений. Можливо, не детальний, але все ж стислий і достовірний пункт. :)
Ям Маркович

2

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


ваша аналогія є приємною
кобі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.