Смущен преимуществом интерпретируемого языка

Меня смущает преимущество интерпретируемого языка, такого как Java, над скомпилированным языком.

Стандартным объяснением преимущества интерпретируемого языка, такого как Java, над скомпилированным языком является то, что один и тот же файл.class может работать на разных типах машинных архитектур. Как это спасет вас от работы?

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

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

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

Благодарю.

4 ответа

Решение

Разве для каждой отдельной машинной архитектуры вам не нужен отдельный компилятор для интерпретации одного и того же файла.class в машинный язык? Так что, если вам нужен свой компилятор для каждой отдельной архитектуры компьютера, чтобы интерпретировать один и тот же файл.class в машинный код, как это спасет вас от работы?

Вышеприведенное утверждение является вашим основным недоразумением.

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

Виртуальная машина Java интерпретирует (и, возможно, компилирует) этот байт-код и выполняет приложение. Эти JVM разработаны для основных архитектур и операционных систем, таких как Windows/Mac/Linux на Intel. Разработчики JVM - это относительно небольшая группа инженеров, таких как Oracle и Sun.

С точки зрения разработчиков приложений, он или она должны компилировать только один раз, потому что байт-код (в файле.class) может быть выполнен на совместимых JVM. Разработчикам приложений не нужно беспокоиться о базовой архитектуре или ОС; они должны только предназначаться для архитектуры JVM. Разработчики JVM - это те, кто имеет дело с базовым уровнем.

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

Java компилируется из исходного кода в промежуточное представление (файлы классов, байт-код) во время сборки. Когда класс загружается впервые, большинство реализаций JVM (включая Oracle HotSpot и IBM J9) проходят кратковременную фазу интерпретации, но если класс будет использоваться с любой частотой, будет работать динамический компилятор (JIT) и скомпилировать в нативный код. (Некоторые JVM, такие как JRockit, переходят непосредственно на native без переводчика.)

Я думаю, что "почему Java не скомпилирована непосредственно в нативный код" - вот настоящий вопрос. Очевидный ответ, как и предполагали другие, это мобильность. Но это более тонко: динамическая компиляция дает более качественный код, чем статическая. Когда код компилируется динамически, JIT знает вещи, которые не может знать ни один статический компилятор: характеристики текущего оборудования (версия процессора, уровень пошагового выполнения, размер строки кэша и т. Д.), А также свойства текущего прогона (благодаря данным профилирования собраны во время интерпретации.) Качество ваших решений зависит от качества вашей информации; динамический компилятор имеет больше и лучше доступной информации, чем статический компилятор, и поэтому может создавать лучший код.

Кроме того, динамические компиляторы имеют возможность выполнять оптимизации, о которых не может мечтать ни один статический компилятор. Например, динамические компиляторы могут проводить спекулятивную оптимизацию и отстаивать ее, если они оказываются неэффективными или если их предположения впоследствии становятся неверными. (См. "Динамическая деоптимизация" здесь: http://www.ibm.com/developerworks/library/j-jtp12214/).

Во-первых, Java является компилируемым языком, а также интерпретируемым языком, потому что вы должны компилировать из.java в.class.

Чтобы понять суть вашего вопроса, преимущество, которое получает Java от (несколько) интерпретации, состоит в том, что вам нужно всего лишь скомпилировать каждую программу, и она может работать на любом компьютере, потому что Java Runtime Environment (JRE), которая компилируется заранее чтобы соответствовать локальной ОС и архитектуре, можно преодолеть этот пробел без (или с минимальной) дальнейшей компиляции.

В неинтерпретированном языке, однако, вы должны скомпилировать каждую программу для каждой ОС и каждой архитектуры, на которой вы хотите, чтобы она выполнялась, что влечет за собой гораздо больше усилий и общего времени компиляции, чем простая компиляция JRE один раз для каждой ОС и архитектуры и компиляция только каждой отдельной программы. запрограммировать один раз.

Было бы непрактично иметь язык, который компилируется для локальной архитектуры каждый раз, когда он запускается, потому что компиляция - довольно интенсивный процесс. Python компилируется при каждом запуске (хотя, как и Java, он компилируется для среды выполнения, а не для локальной архитектуры), и это один из самых медленных языков.

Надеюсь, это помогло прояснить ситуацию.

Мне нравится ответ sowrd299. Мои два цента:

  • у вас технически бесконечные разные целевые архитектуры
  • и, следовательно, компиляция кода для всех целей одновременно и упаковка его вместе приведет к бесконечно большому исполняемому файлу
  • поэтому компиляция Java на основе байт-кода виртуальной машины является лучшим решением: поскольку она имеет только одну целевую архитектуру
  • в то время как разработчики могут отдельно добавлять JVM для всех новых и старых архитектур, что позволяет всем новым компонентам (таким как Raspberry PI) запускать ваш Java-код, скомпилированный в прошлом веке.

С другой стороны, "компиляция для нескольких целей заранее" не является абсолютно безумной вещью. Afaik Windows Universal Apps работает следующим образом: это одно и то же приложение в том же exe-файле, но на самом деле исполняемый файл содержит код, скомпилированный для 80x86, а также для цели ARM. Таким образом, одно приложение выглядит переносимым среди Windows Mobile и настольных решений без какой-либо дальнейшей интерпретации.

Другие вопросы по тегам