Как точно компиляция Java происходит?

Перепутанный процессом компиляции Java

Хорошо я знаю это: Мы пишем исходный код Java, компилятор, который независим от платформы, переводит его в байт-код, затем jvm, который является зависимым платформы, переводит его в машинный код.

Таким образом от запуска, мы пишем исходный код Java. Компилятор javac.exe является .exe файлом. Каков точно этот .exe файл? Разве компилятор Java не записан в Java, затем каким образом существует .exe файл, который выполняет его? Если компилируемый код записан, Java, то, каким образом компилируемый код выполняется на этапе компиляции, так как это - задание jvm для выполнения кода Java. Как может сам язык компилировать свой собственный код языка? Все это походит на проблему курицы и яйца мне.

Теперь, что точно .class файл содержит? Действительно ли это - абстрактное синтаксическое дерево в текстовой форме, это табличная информация, что это?

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

59
задан nash 4 August 2010 в 15:12
поделиться

7 ответов

Хорошо, я знаю это: мы пишем исходный код Java, компилятор, который не зависит от платформы, переводит его в байт-код,

Фактически сам компилятор работает как собственный исполняемый файл (следовательно, javac.exe). И правда, он преобразует исходный файл в байт-код. Байт-код не зависит от платформы, потому что он нацелен на виртуальную машину Java.

тогда jvm, который зависит от платформы, переводит его в машинный код.

Не всегда. Что касается JVM Sun, существует две jvms: клиентская и серверная. Они оба могут, но не обязательно должны компилироваться в собственный код.

Итак, с самого начала мы пишем исходный код java. Компилятор javac.exe - это.EXE файл. Что именно это за файл .exe? Разве компилятор java не написан на java, тогда почему же существует файл .exe, который его выполняет?

Этот exe файл представляет собой обернутый байт-код java. Это для удобства - чтобы не было сложных пакетных скриптов. Он запускает JVM и выполняет компилятор.

Если код компилятора написан на java, то почему код компилятора выполняется на этапе компиляции, поскольку это задача jvm по выполнению кода java.

Именно это и делает код упаковки.

Как язык сам может составить свой собственный языковой код? Мне все это кажется проблемой с курицей и яйцом.

Правда, сбивает с толку на первый взгляд. Впрочем, это не только идиома Java. Компилятор Ады также написан на самой Аде. Это может выглядеть как «проблема с курицей и яйцом», но на самом деле это всего лишь проблема начальной загрузки.

Что именно содержится в файле .class? Это абстрактное синтаксическое дерево в текстовой форме, это табличная информация, что это?

Это не абстрактное синтаксическое дерево. AST используется только токенизатором и компилятором во время компиляции для представления кода в памяти. .class файл похож на сборку, но для JVM. JVM, в свою очередь, представляет собой абстрактную машину, которая может запускать специализированный машинный язык, ориентированный только на виртуальную машину. В самом простом случае файл .class имеет структуру, очень похожую на обычную сборку. Вначале объявляются все статические переменные, затем идет несколько таблиц сигнатур внешних функций и, наконец, машинный код.

Если Вам действительно интересно, Вы можете покопаться в файле классов с помощью утилиты "javap".Вот пример (запутанный) вывода при вызове javap -c Main :

0:   new #2; //class SomeObject
3:   dup
4:   invokespecial   #3; //Method SomeObject."<init>":()V
7:   astore_1
8:   aload_1
9:   invokevirtual   #4; //Method SomeObject.doSomething:()V
12:  return

Итак, вы уже должны иметь представление, что это такое на самом деле.

Кто-нибудь может мне ясно и подробно рассказать о том, как мой исходный код Java преобразуется в машинный код.

Я думаю, что сейчас это должно быть более ясным, но вот краткое резюме:

  • Вы вызываете javac , указывая на файл исходного кода. Внутренний ридер (или токенизатор) javac читает ваш файл и строит из него настоящий AST. Все синтаксические ошибки происходят именно на этом этапе.

  • javac еще не завершил свою работу. Когда он имеет AST, можно начинать настоящую компиляцию. Он использует шаблон посетителя для обхода AST и разрешает внешние зависимости, чтобы добавить смысл (семантику) к коду. Готовый продукт сохраняется в виде файла .class , содержащего байт-код.

  • Теперь пора запустить эту штуку. Вы вызываете java с именем файла .class. Теперь JVM запускается снова, но для интерпретации вашего кода. JVM может или не может компилировать Ваш абстрактный байт-код в собственную сборку. Компилятор Sun HotSpot в сочетании с компиляцией Just In Time может сделать это, если это необходимо. Выполняемый код постоянно профилируется JVM и перекомпилируется в собственный код при соблюдении определенных правил. Чаще всего первым компилируется код hot .

Редактировать: Без javac компилятор пришлось бы вызывать, используя что-то вроде этого:

%JDK_HOME%/bin/java.exe -cp:myclasspath com.sun.tools.javac.Main fileToCompile

Как вы можете видеть, он вызывает частный API Sun, поэтому он привязан к реализации Sun JDK.Это сделало бы системы сборки зависимыми от него. Если один переключился на любой другой JDK (вики перечисляет 5, кроме Sun)тогда приведенный выше код следует обновить, чтобы отразить это изменение (поскольку маловероятно, что компилятор будет находиться в пакете com.sun.tools.javac). Другие компиляторы могут быть написаны в машинном коде.

Стандартный способ - отправить оболочку javac с JDK.

60
ответ дан 24 November 2019 в 18:27
поделиться

Компилятор javac.exe - это файл .exe. Что именно это за файл .exe? Не компилятор java, написанный на java, тогда как получилось, что есть файл .exe, который выполняет его?

Компилятор Java (по крайней мере, тот, который поставляется с Sun / Oracle JDK) действительно написан на Java. javac.exe - это просто программа запуска, которая обрабатывает аргументы командной строки, некоторые из которых передаются JVM, запускающей компилятор, а другие - самому компилятору.

Если код компилятора написан, это java, тогда почему код компилятора выполняется на этапе компиляции, так как это работа jvm для выполнить java-код. Как язык сам скомпилировать свой языковой код? Все похоже на курицу и яйцо проблема для меня.

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

Что именно делает файл .class содержать? Это абстрактное синтаксическое дерево в текстовой форме, это табличное информация, что это такое?

Подробности формата файла класса описаны в спецификации виртуальной машины Java .

11
ответ дан 24 November 2019 в 18:27
поделиться

Ну, javac и jvm обычно являются собственными двоичными файлами. Они написаны на C или как-то еще. Конечно, можно написать их на Java, просто вам сначала нужна нативная версия. Это называется «обвязкой ботинка».

Интересный факт: большинство компиляторов, которые компилируются в машинный код, написаны на их собственном языке. Однако все они сначала должны были иметь родную версию, написанную на другом языке (обычно C). Для сравнения: первый компилятор C был написан на Ассемблере. Я предполагаю, что первый ассемблер был написан на машинном коде. (Или с использованием бабочек ;)

.class-файлы - это байт-код, сгенерированный javac. Они не текстовые, это двоичный код, похожий на машинный (но с другим набором инструкций и архитектурой).

jvm во время выполнения имеет два варианта: он может либо интерпретировать байтовый код (притворяясь самим процессором), либо он может JIT (точно в срок) скомпилировать его в собственный машинный код. Последний, конечно, быстрее, но сложнее.

5
ответ дан 24 November 2019 в 18:27
поделиться

Файл .class содержит байт-код, который является своего рода , как сборка очень высокого уровня . Компилятор вполне может быть написан на Java, но JVM нужно будет скомпилировать в собственный код, чтобы избежать проблемы с курицей / яйцом. Я считаю, что он написан на C, как и нижние уровни стандартных библиотек. Когда JVM запускается, она выполняет своевременную компиляцию, чтобы превратить этот байт-код в собственные инструкции.

3
ответ дан 24 November 2019 в 18:27
поделиться

Разве компилятор java не написан на java, тогда почему .exe файл, который его выполняет?

Откуда вы берете эту информацию? Исполняемый файл javac может быть написан на любом языке программирования, это не имеет значения, важно только то, что это исполняемый файл, который превращает файлы .java в .class . ] файлы.

Для получения подробной информации о двоичной спецификации файла .class вы можете найти эти главы в Java Language Specification полезными (хотя, возможно, немного техническими):

Вы также можете взглянуть на Спецификацию виртуальной машины , которая охватывает:

16
ответ дан 24 November 2019 в 18:27
поделиться

Изначально компилятор был написан на C с использованием битов C ++, и я предполагаю, что так оно и есть до сих пор (как вы думаете, почему компилятор также написан на Java?). javac.exe - это просто код C / C ++, который является компилятором.

В качестве побочного момента вы можете написать компилятор на java, но вы правы, вам нужно избегать проблемы с курицей и яйцом. Для этого вы обычно пишете один или несколько инструментов начальной загрузки на чем-то вроде C, чтобы иметь возможность скомпилировать компилятор.

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

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

-1
ответ дан 24 November 2019 в 18:27
поделиться

Windows не знает, как вызывать Java-программы до установки среды выполнения Java, и Sun предпочла иметь нативные команды, которые собирают аргументы, а затем вызывают JVM, вместо того чтобы привязывать jar-суффикс к Java-движку.

1
ответ дан 24 November 2019 в 18:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: