Spec-Zone .ru
спецификации, руководства, описания, API
|
Содержание | Предыдущий | Следующий | Индекс | Спецификация Виртуальной машины JavaTM |
Это приложение обсуждает различия между оригинальной версией Спецификации Виртуальной машины JavaTM и существующей версией. Его цель является двукратной: суммировать, что изменения были произведены и объяснить, почему они были сделаны.
Всюду по этому приложению мы обращаемся к оригинальной версии Спецификации Виртуальной машины JavaTM (то есть, первая опубликованная версия этой книги) как исходная спецификация или исходная спецификация виртуальной машины Java. Мы именуем текущую книгу как пересмотренную спецификацию. Мы обозначаем первый выпуск Спецификации языка JavaTM как просто Спецификация языка JavaTM.
Пересмотренная спецификация стремится прояснить мысли, которые давали начало недоразумению и исправлять неоднозначности, ошибки, и пропуск в исходной спецификации.
За исключением обработки вычисления с плавающей точкой, различия между пересмотренной спецификацией и ее предшественником не имеют никакого эффекта на допустимые программы, записанные в языке программирования Java. Версии влияют только, как виртуальная машина обрабатывает неправильные программы. Во многих из этих экземпляров большинство реализаций не реализовывало исходную спецификацию. Пересмотренная спецификация документирует намеченное поведение.
Самые очевидные изменения находятся в спецификации типов с плавающей точкой и операций; class
проверка файла; инициализация, загрузка, и соединение; и инструкции вызова метода. Кроме того, несколько других важных исправлений были сделаны.
Пересмотренная спецификация также ошибки исправлений или разъясняют проблемы, на которые обратили наше внимание читатели исходной спецификации.
В то время как мы приложили все усилия, чтобы исправить так много проблем насколько возможно, мы распознаем, что дополнительные улучшения принесли бы пользу этой спецификации. В частности мы полагаем что описание class
проверка файла должна быть далее усовершенствована, идеально на грани образования формальной спецификации. Мы ожидаем, что будущие версии будут адресовать остающиеся слабые места и исправлять любые ошибки, о которых недавно сообщают, сохраняя неизменный семантика языка программирования Java.
Следующие разделы обсуждают изменения к исходной спецификации более подробно и объясняют, почему изменения были необходимы.
В результате этого изменения реализации на процессорах, которые более естественно и эффективно поддерживают форматы расширенной точности и операции с плавающей точкой на форматах расширенной точности, могут поставить лучшую производительность для вычислений с плавающей точкой. Реализации на процессорах, которые естественно и эффективно реализуют единственный IEEE 754 - и операции двойной точности как передано под мандат исходной спецификацией, могут продолжать делать так. Поведение с плавающей точкой любой реализации виртуальной машины Java, которая соответствует исходной спецификации также, соответствует пересмотренной спецификации.
class
Проверка файлаclass
проверка файла состоит в том, что каждая реализация виртуальной машины Java должна фактически выполнить проверку. Это утверждается однозначно в
Спецификация языка JavaTM. Исходная спецификация виртуальной машины Java, содержавшей несколько вводящих в заблуждение предложений, которые привели некоторых читателей приходить к заключению, что проверка была дополнительной. Обсуждение class
формат файла в Главе 4 также исправляет много маленьких ошибок в исходной спецификации. Старшие значащие из этих исправлений:
<clinit>
методы).
CONSTANT_Fieldref_info
может быть интерфейсный тип, так как интерфейсы могут содержать static
поля.
native
или abstract
не может иметь a Code
атрибут.
class
проверка файла больше не запрещает попытки вызвать abstract
методы; см. полное обсуждение этой проблемы позже в этом приложении. Очевидный беспорядок по обстоятельствам, инициировавшим инициализацию, ведомую нас, чтобы перефразировать спецификацию того, когда инициализация происходит (§2.17.4). Однако, эта перефразированная спецификация эквивалентна оригиналу.
Одно из исходных требований было то, что класс будет инициализирован в первый раз, когда один из его конструкторов вызывается. В языке программирования Java вызов конструктора составляет создание экземпляра. Кроме того, так как никакой метод экземпляра не может быть вызван, если никакие экземпляры не существуют, это является четким, для которого требование, чтобы класс быть инициализированным в первый раз один из его методов был вызван, важно только static
методы. Подобным рассуждением, требование, чтобы класс быть инициализированным, если к какому-либо из его полей получают доступ, применялся только к static
поля.
Исходная спецификация точно не описывала обстоятельства, которые инициируют инициализацию на уровне виртуальной машины Java (см. обсуждение позже в этом приложении). Разделите 5.5, теперь дает простое и точное определение с точки зрения инструкций виртуальной машины Java.
Ключевые изменения включают следующее:
Описание класса, загружающегося в исходной спецификации, не утверждало что, разрешая класс, требуемый его суперинтерфейсы, которые будут разрешены. Это было ошибкой в ранних реализациях виртуальной машины Java, которая была исправлена.
Описание CONSTANT_Class_info
разрешение в Разделе 5.1.1 из исходной спецификации, подразумеваемой, что разрешение ссылки на класс заставляет это быть соединенным. В то время как это было верно для реализации виртуальной машины Java Sun, описание было более рестриктивным чем
Спецификация языка JavaTM, которая ясно утверждает, что у реализаций виртуальной машины Java есть гибкость в синхронизации соединения действий. Пересмотренная спецификация виртуальной машины Java соглашается со
Спецификацией языка JavaTM по этой проблеме.
Описание CONSTANT_Class_info
разрешение в Разделе 5.1.1 из исходной спецификации, подразумеваемой, что разрешение класса заставляет это быть инициализированным. Однако, исходная спецификация, также включенная противоречащий оператор, что инициализация должна произойти только на первом активном использовании класса. В реализации виртуальной машины Java, которая выполняет ленивое разрешение, различие является тонким. В других реализациях различие является намного более четким. Например, нетерпеливое разрешение явно позволяется
Спецификацией языка Java. Если бы разрешение всегда вызываемая инициализация, такая реализация была бы вынуждена выполнить нетерпеливую инициализацию в четком противоречии к
Спецификации языка JavaTM. Противоречие разрешается, разъединяя разрешение от инициализации.
Тесно связанной проблемой является оператор в Разделе 5.1.2 из исходной спецификации что loadClass
метод класса ClassLoader
может заставить инициализацию происходить, если ее второй параметр true
. Это противоречит
Спецификации языка JavaTM, которая утверждает, что только загрузка и соединение происходят в этом случае. Снова, противоречие было разрешено, чтобы соответствовать
Спецификации языка JavaTM по по существу тем же самым причинам.
ClassLoader.loadClass(String)
. Исходная спецификация, утвержденная, что, загружая класс или интерфейс, используя определяемый пользователем загрузчик класса виртуальная машина Java вызывает метод с двумя параметрами ClassLoader.loadClass(String,
boolean)
. Цель boolean
параметр должен был указать, должно ли соединение иметь место. Однако, было отмечено на странице 144 исходной спецификации, что этот интерфейс, вероятно, изменится. Это было распознано, что возложение ответственности за соединение на загрузчике класса было и несоответствующим и ненадежным.
Начинаясь с выпуска 1.1 JDK, соединение обрабатывается непосредственно виртуальной машиной Java. Дополнительный метод loadClass(String)
был также добавлен к классу ClassLoader
. Этот метод может так же быть вызван виртуальной машиной Java. Пересмотренная спецификация определяет класс, загружающийся с точки зрения нового метода. Две версии параметра все еще сохраняются в Java 2 платформы v1.2 в интересах совместимости, но не играют роли в пересмотренной спецификации.
Тонкость безопасного с точки зрения типов редактирования в присутствии многократных, определяемых пользователем загрузчиков класса не достаточно ценилась, когда исходная спецификация была записана. Это впоследствии стало четким, что гарантируется подробное описание загружающихся ограничений на типы времени выполнения. Конечно, присутствие загружающихся ограничений заметно только недопустимыми программами.
Эти правила следуют Из Спецификации языка JavaTM, но были оставлены неявными в исходной спецификации. Правила соответствуют поведению существующих реализаций.
Разделите 5.1.1 из исходной спецификации, утверждает это a NoClassDefFoundError
должен быть брошен, если представление класса или интерфейса недопустимо. Однако, оба
Спецификация языка JavaTM и Раздел 2.16.2 из исходной спецификации утверждают это a ClassFormatError
бросается в этом случае. Ясно, a ClassFormatError
является более соответствующим.
Исходная спецификация была неясна относительно того, должно ли, во время метода или полевого разрешения, поле, на которое ссылаются, было быть объявлено в точном классе, на который ссылаются, или могло быть наследовано. Это привело к изменениям среди реализаций виртуальной машины Java и несогласованности между Спецификацией виртуальной машины Java и Спецификацией языка JavaTM. Пересмотренная спецификация дает более точное описание, которое соглашается с поведением большинства реализаций, но не со Спецификацией языка JavaTM. Спецификация языка JavaTM будет исправлена в ее следующем выпуск.
Этот выбор дает программистам гибкость движущихся методов и полей в иерархии классов в то время как сдерживающая совместимость на уровне двоичных кодов с предыдущими реализациями их программ.
AbstractMethodError
возможно, не повышается во время подготовки.
Спецификация языка JavaTM требует, чтобы добавление метода к интерфейсу было двоичным совместимым изменением. Однако, Разделы 5.1.1 и 2.16.3 из исходной спецификации требуют, чтобы подготовка отклонила класс, который имеет abstract
метод, если тот класс не самостоятельно abstract
. Последнее требование противоречит прежнему.
Рассмотрите случай интерфейса, который я реализовывал классом C, который не является abstract
. Если новый метод добавляется к, я, C должен реализовать его. Однако, если старая версия C будет использоваться вместе с новой версией, то я во время выполнения, C буду действительно иметь abstract
метод. Если подготовка должна была повысить AbstractMethodError
в этом случае добавляя метод к я не был бы двоичным совместимым изменением, так как это приведет к разовому ссылкой отказу. Следовательно, проверка во время для подготовки была отброшена. У этого изменения есть импликации для вызова метода, как обсуждено ниже.
Описание в Разделе 5.3 из исходной спецификации, опущенной проверки, требуется во время интерфейсного разрешения метода. Эти проверки (что интерфейс, на который ссылаются, существует и что метод, на который ссылаются, существует в том интерфейсе) требуются Спецификацией языка JavaTM и выполняются наиболее широко используемыми реализациями виртуальной машины Java. Проверки документируются в Раздел 5.4.3.4 из пересмотренной спецификации.
Как следствие разъединения класса и интерфейсной инициализации от разрешения, стало необходимо определить, когда виртуальная машина Java инициировала инициализацию. Эта спецификация дается в Разделе 5.5 из пересмотренной спецификации. Как отмечено ранее, это описание соглашается со спецификацией событий в инициализации инициирования уровня языка программирования Java, данной в Разделе 2.17.4 из пересмотренной спецификации.
Описания инструкций вызова метода, использованных известное понятие метода, диспетчеризируют таблицу. Таблицы метода использовались в качестве описательных устройств, но к сожалению многих читателей по ошибке мысль, что использование таких таблиц было требованием спецификации. Чтобы прояснить эту мысль, алгоритм поиска дается вместо этого.
Исходная спецификация иногда перечисляемые исключения, которые могли быть повышены инструкцией согласно их позиции в иерархии исключения, а не тем, когда они могли бы произойти. Это использование было непоследовательно и иногда ошибочно.
Намерение категорий, Соединяющих Исключения и Исключения на этапе выполнения в конце каждого описания инструкции, состоит в том, чтобы описать в том, какая фаза выполнения ошибка будет брошена. Важным примером этого является обработка UnsatisfiedLinkError
. Описания всех инструкций вызова метода определяют это native
методы связываются во время выполнения, если они уже не были связаны. Если обязательные сбои, UnsatisfiedLinkError
бросается. Однако, UnsatisfiedLinkError
последовательно перечисляется в описаниях инструкции исходной спецификации как Соединение Исключения. Прояснить, что исключение фактически выдается во время выполнения, пересмотренные списки спецификации UnsatisfiedLinkError
как Исключение на этапе выполнения в описаниях всех инструкций вызова метода.
Другой экземпляр этой проблемы был в описании invokeinterface инструкции. Во время выполнения фактически произошло большинство исключений, перечисленных в исходной спецификации invokeinterface как Соединение Исключений. Они перечисляются в пересмотренной спецификации как Исключения на этапе выполнения.
abstract
методы во время выполнения.
Это - прямой результат устранения abstract
проверка метода во время класса или интерфейсная подготовка, как обсуждено ранее. В то время как во многих случаях использование abstract
метод на классе, который не является abstract
все еще приведет к разовой ссылкой ошибке, возможно создать случаи, где ошибка не будет происходить до времени выполнения.
Рассмотрите abstract
класс A с abstract
метод foo
и бетон разделяет B на подклассы. Если B забыл реализовывать foo
, тогда метод
void bar(A
a) {a.foo();}
перестанет работать если вызвано на экземпляр B. Это не будет обнаружено во время ссылки, но во время выполнения. В результате invokeinterface и invokevirtual могут повысить AbstractMethodError
во время выполнения.
Описание invokeinterface инструкции теперь утверждает, что цель вызова метода должна поддерживать интерфейс, на который ссылаются. Это требуется Спецификацией языка JavaTM и было свойством всех главных реализаций виртуальной машины Java в течение некоторого времени.
Второй маркер на странице 261 исходной спецификации был избыточен и был удален. Другие маркеры были переупорядочены, и факт, что обычно разрешенный метод выбирается для выполнения, утверждался явно. Эти изменения не изменяют спецификацию всегда, но служат только, чтобы сделать текст более понятным.
Innerclasses
и Synthetic
атрибуты, описанные в пересмотренной спецификации в Разделе 4.7.5 и Разделе 4.7.6, соответственно, были добавлены в выпуске 1.1 JDK, чтобы поддерживать вложенные классы. К сожалению, мы не были в состоянии включать описание вложенных классов в кратком обзоре языка программирования Java, данном в Главе 2. Полное описание будет включено в следующего выпуск
Спецификация языка JavaTM. До тех пор сошлитесь на документацию относительно всемирной паутины в http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses
Глава была удалена из пересмотренной спецификации. Метод оптимизации, который это описало, теперь хорошо понимается. Что более важно, метод точно как описано не используется многими из реализаций виртуальной машины Java, включая часть Sun, разработанного, так как исходная спецификация была опубликована. Значение главы, чтобы оснастить писателей уменьшилось по той же самой причине. Таким образом глава теперь лучше всего замечается как документация для определенной реализации виртуальной машины Java, делая это несоответствующий для спецификации виртуальной машины Java.
class
формат файла изменился. Номер основной версии теперь предназначается, чтобы соответствовать новым главным версиям платформы (например, Java 2 платформы, Standard Edition, v1.2), в то время как номер вспомогательной версии может использоваться, чтобы представить уровни выпуска реализаций платформы (например, Java 2 SDK, Standard Edition, v1.2.1). Начиная с первого общедоступного выпуска платформы Java, всех class
файлы были сгенерированы, используя номер основной версии 45 и номер вспомогательной версии 3. Следовательно, нет существующий правильно построенный class
на файл влияет это изменение в интерпретации.
class
файлы с исторически используемыми номерами версий.
final
. Это документирует поведение существующих реализаций.
IllegalMonitorStateException
. Исходная спецификация, неявно учтенная повышение такого исключения как следствие Раздела 8.5: Разблокировать работа потоком T на блокировке L может произойти, только если число предыдущих разблокировало операции T на L, строго меньше чем число предыдущих операций блокировки T на L.
и Раздел 8.13:
Если выполнение тела метода когда-либо завершается, или обычно или резко, разблокировать работа автоматически выполняется на той же самой блокировке.
Однако, это не было четко дано понять и явно.
synchronized
операторы, данные в Разделе 8.13 из исходной спецификации, были ошибочны. Это утверждало следующее: Если выполнение тела когда-либо завершается, или обычно или резко, разблокировать работа автоматически выполняется на той же самой блокировке.
Это - свойство программ, записанных в языке программирования Java, гарантируемом корректными компиляторами для языка программирования Java; это не гарантируется виртуальной машиной Java. Однако, программы действительно делают структурированное использование из блокировки, и реализации виртуальной машины Java могут положиться и осуществить это свойство. Соответствующие правила даются в исправленной версии Раздела 8.13. Как следствие тех правил, IllegalMonitorStateException
исключения могут быть повышены инструкциями возврата и athrow, и инструкциями вызова метода, вызывая native
методы.
Deprecated
атрибут, атрибут, представленный в выпуске 1.1 JDK, чтобы поддерживать @deprecated
тег в комментариях для документации, был определен. Присутствие a Deprecated
атрибут не изменяет семантику класса или интерфейса. Содержание | Предыдущий | Следующий | Индекс
Спецификация Виртуальной машины JavaTM
Авторское право © Sun Microsystems, Inc 1999 года. Все права защищены
Пожалуйста, отправьте любые комментарии или исправления к jvm@java.sun.com