Глава 1. Введение
Содержание
Язык программирования Java® — это универсальный, конкурентный, основанный на классах, объектно-ориентированный язык. Он разработан таким образом, чтобы быть достаточно простым, чтобы многие программисты могли овладеть им. Язык программирования Java связан с C и C++, но организован совершенно иначе, с исключением ряда аспектов C и C++ и включением нескольких идей из других языков. Он предназначен для использования в производстве, а не в научных исследованиях, и поэтому, как предложил К. А. Р. Хоар в своей классической статье по разработке языков, при разработке были исключены новые и не проверенные функции.
Язык программирования Java — язык со строгой и статической типизацией. В данной спецификации четко различаются ошибки времени компиляции, которые могут и должны быть обнаружены на этапе компиляции, и те, которые возникают во время выполнения. Этап компиляции обычно включает в себя перевод программ в независимую от машины байт-кодовую форму представления. Действия во время выполнения включают загрузку и связывание классов, необходимых для выполнения программы, необязательное преобразование в машинный код и динамическую оптимизацию программы, а также фактическое выполнение программы.
Язык программирования Java — язык сравнительно высокого уровня, так как детали машинного представления недоступны через язык. Он включает в себя автоматическое управление памятью, как правило, с использованием сборщика мусора, чтобы избежать проблем безопасности явного удаления (как в C's free или C++'s delete). Высокопроизводительные реализации с сборщиком мусора могут иметь ограниченные паузы для поддержки системного программирования и приложений реального времени. Язык не содержит никаких небезопасных конструкций, таких как доступ к массивам без проверки индексов, так как такие небезопасные конструкции могут привести к поведению программы, не определенному в спецификации.
Язык программирования Java обычно компилируется в наборы инструкций и двоичный формат байт-кода, определенные в Спецификации виртуальной машины Java, издание Java SE 11.
В главе 2 описываются грамматики и обозначения, используемые для представления лексических и синтаксических грамматик языка.
Глава 3 описывает лексическую структуру языка программирования Java, основанную на C и C++. Язык написан в наборе символов Unicode. Он поддерживает написание символов Unicode на системах, поддерживающих только ASCII.
В главе 4 описываются типы, значения и переменные. Типы подразделяются на примитивные и ссылочные типы.
Примитивные типы определены одинаково на всех машинах и во всех реализациях и представляют собой различные размеры целых чисел со знаком «два дополнения», одно- и двойной точности чисел с плавающей точкой стандарта IEEE 754, тип boolean и тип символа Unicode char. Значения примитивных типов не разделяют состояние.
Ссылочные типы – это типы классов, типы интерфейсов и типы массивов. Ссылочные типы реализуются динамически создаваемыми объектами, которые являются экземплярами классов или массивов. Может существовать множество ссылок на каждый объект. Все объекты (включая массивы) поддерживают методы класса Object, который является (единственным) корнем иерархии классов. Предварительно определенный класс String поддерживает строки символов Unicode. Существуют классы для упаковки примитивных значений внутри объектов. Во многих случаях упаковка и распаковка выполняются компилятором автоматически (в этом случае упаковка называется боксерной, а распаковка – распаковкой). Объявления классов и интерфейсов могут быть обобщенными, то есть они могут быть параметризованы другими ссылочными типами. Такие объявления затем могут быть вызваны со специфическими аргументами типов.
Переменные – это типизированные места хранения. Переменная примитивного типа хранит значение того же примитивного типа. Переменная типа класса может содержать нулевую ссылку или ссылку на объект, тип которого является типом этого класса или любым подклассом этого класса. Переменная типа интерфейса может содержать нулевую ссылку или ссылку на экземпляр любого класса, реализующего интерфейс. Переменная типа массива может содержать нулевую ссылку или ссылку на массив. Переменная типа класса Object может содержать нулевую ссылку или ссылку на любой объект, будь то экземпляр класса или массив.
Глава 5 описывает преобразования и числовые повышения. Преобразования изменяют тип выражения во время компиляции и иногда значение выражения. Эти преобразования включают преобразования между примитивными и ссылочными типами посредством упаковки и распаковки. Числовые повышения используются для преобразования операндов числового оператора к общему типу, где операцию можно выполнить. В языке нет лазеек; приведение типов ссылочных типов проверяется во время выполнения для обеспечения безопасности типов.
Глава 6 описывает объявления и имена и то, как определить, что означают имена (то есть, какое объявление обозначает имя). Язык программирования Java не требует объявления классов и интерфейсов или их членов до их использования. Порядок объявления имеет значение только для локальных переменных, локальных классов и порядка инициализаторов полей в классе или интерфейсе. Здесь описываются рекомендуемые соглашения об именах, которые делают программы более читабельными.
Глава 7 описывает структуру программы, организованной в пакеты. Членами пакета являются классы, интерфейсы и подпакеты. У пакетов, а следовательно, и их членов, есть имена в иерархическом пространстве имен; система доменных имен Интернета обычно может использоваться для формирования уникальных имен пакетов. Единицы компиляции содержат объявления классов и интерфейсов, которые являются членами данного пакета, и могут импортировать классы и интерфейсы из других пакетов, чтобы дать им короткие имена.
Пакеты могут быть сгруппированы в модули, которые служат строительными блоками при создании очень больших программ. Объявление модуля указывает, какие другие модули (и, следовательно, пакеты, а следовательно, классы и интерфейсы) необходимы для компиляции и запуска кода в собственных пакетах.
Язык программирования Java поддерживает ограничения на внешний доступ к членам пакетов, классов и интерфейсов. Члены пакета могут быть доступны только другим членам в том же пакете или членам в других пакетах того же модуля или членам пакетов в разных модулях. Аналогичные ограничения применяются к членам классов и интерфейсов.
Глава 8 описывает классы. Членами классов являются классы, интерфейсы, поля (переменные) и методы. Переменные класса существуют один раз на класс. Методы класса работают без ссылки на конкретный объект. Переменные экземпляра динамически создаются в объектах, являющихся экземплярами классов. Методы экземпляра вызываются на экземплярах классов; такие экземпляры становятся текущим объектом this во время их выполнения, поддерживая объектно-ориентированный стиль программирования.
Классы поддерживают одиночное наследование, в котором каждый класс имеет один суперкласс. Каждый класс наследует члены от своего суперкласса и в конечном итоге от класса Object. Переменные типа класса могут ссылаться на экземпляр этого класса или любого подкласса этого класса, что позволяет использовать новые типы с существующими методами полиморфно.
Классы поддерживают параллельное программирование с методами synchronized. Методы объявляют проверяемые исключения, которые могут возникнуть в результате их выполнения, что позволяет проверить во время компиляции, чтобы гарантировать, что исключительные ситуации обрабатываются. Объекты могут объявлять метод finalize, который будет вызываться перед тем, как объекты будут удалены сборщиком мусора, позволяя объектам очищать свое состояние.
Для простоты язык не имеет разделения объявлений «заголовков» от реализации класса или отдельных иерархий типов и классов.
Особая форма классов, перечисления, поддерживает определение небольших наборов значений и их манипулирование безопасным способом. В отличие от перечислений в других языках, перечисления являются объектами и могут иметь свои собственные методы.
Глава 9 описывает интерфейсы. Членами интерфейсов являются классы, интерфейсы, константные поля и методы. Классы, которые в противном случае не связаны, могут реализовывать один и тот же интерфейс. Переменная типа интерфейса может содержать ссылку на любой объект, реализующий интерфейс.
Классы и интерфейсы поддерживают множественное наследование от интерфейсов. Класс, реализующий один или несколько интерфейсов, может унаследовать методы экземпляров от своего суперкласса и своих суперинтерфейсов.
Типы аннотаций – это специализированные интерфейсы, используемые для аннотирования объявлений. Такие аннотации не допускается каким-либо образом влиять на семантику программ на языке программирования Java. Однако они предоставляют полезный ввод для различных инструментов.
Глава 10 описывает массивы. Доступ к массивам включает проверку границ. Массивы являются динамически создаваемыми объектами и могут быть назначены переменным типа Object. Язык поддерживает массивы массивов, а не многомерные массивы.
Глава 11 описывает исключения, которые не возобновляются и полностью интегрированы в семантику языка и механизмы параллельности. Существует три типа исключений: проверяемые исключения, исключения времени выполнения и ошибки. Компилятор гарантирует, что проверяемые исключения должным образом обрабатываются, требуя, чтобы метод или конструктор мог вызвать проверяемое исключение только в том случае, если метод или конструктор его объявляет. Это обеспечивает проверку во время компиляции наличия обработчиков исключений и помогает программировать на больших масштабах. Большинство определяемых пользователем исключений должны быть проверяемыми исключениями. Некорректные операции в программе, обнаруженные виртуальной машиной Java, приводят к исключениям времени выполнения, таким как NullPointerException. Ошибки возникают из-за сбоев, обнаруженных виртуальной машиной Java, таких как OutOfMemoryError. Большинство простых программ не пытаются обрабатывать ошибки.
Глава 12 описывает действия, происходящие во время выполнения программы. Программа обычно хранится как двоичные файлы, представляющие скомпилированные классы и интерфейсы. Эти двоичные файлы могут быть загружены в виртуальную машину Java, связаны с другими классами и интерфейсами и инициализированы.
После инициализации можно использовать методы и переменные класса. Некоторые классы могут быть созданы для создания новых объектов типа класса. Объекты, которые являются экземплярами класса, также содержат экземпляр каждого суперкласса класса, а создание объекта включает рекурсивное создание этих экземпляров суперкласса.
Когда объект больше не ссылается, он может быть возвращен сборщиком мусора. Если объект объявляет финализатор, финализатор выполняется до того, как объект возвращается сборщиком мусора, чтобы дать объекту последнюю возможность очистить ресурсы, которые в противном случае не были бы освобождены. Когда класс больше не нужен, он может быть загружен.
Глава 13 описывает двоичную совместимость, определяя влияние изменений в типах на другие типы, которые используют измененные типы, но не были перекомпилированы. Эти соображения представляют интерес для разработчиков типов, которые должны широко распространяться в непрерывной серии версий, часто через Интернет. Хорошие среды разработки программ автоматически перекомпилируют зависимый код всякий раз, когда тип изменяется, поэтому большинство программистов не должны беспокоиться об этих деталях.
Глава 14 описывает блоки и операторы, основанные на C и C++. Язык не имеет оператора goto, но включает помеченные операторы break и continue. В отличие от C, язык программирования Java требует boolean (или Boolean) выражений в операторах управления потоком и не преобразует типы в boolean неявно (кроме распаковки), в надежде поймать больше ошибок на этапе компиляции. Оператор synchronized предоставляет базовый мониторинг блокировки на уровне объектов. Оператор try может включать в себя предложения catch и finally, чтобы защититься от нелокальных передач управления.
Глава 15 описывает выражения. Этот документ полностью определяет (видимый) порядок оценки выражений для повышения детерминизма и переносимости. Перегруженные методы и конструкторы разрешаются во время компиляции, выбирая наиболее специфичный метод или конструктор из применимых.
Глава 16 описывает точный способ, которым язык гарантирует, что локальные переменные определенно устанавливаются перед использованием. В то время как все остальные переменные автоматически инициализируются значениями по умолчанию, язык программирования Java не автоматически инициализирует локальные переменные, чтобы избежать маскировки ошибок программирования.
Глава 17 описывает семантику потоков и блокировок, которые основаны на основанной на мониторах параллельности, первоначально представленной в языке программирования Mesa. Язык программирования Java определяет модель памяти для многопроцессорных систем с общей памятью, которая поддерживает высокопроизводительные реализации.
Глава 18 описывает различные алгоритмы вывода типов, используемые для проверки применимости обобщенных методов и вывода типов в вызовах обобщенных методов.
Глава 19 представляет синтаксическую грамматику языка.
Большинство примеров программ, приведенных в тексте, готовы к выполнению и имеют форму, подобную:
class Test {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++)
System.out.print(i == 0 ? args[i] : " " + args[i]);
System.out.println();
}
}
На компьютере с установленным Oracle JDK этот класс, хранящийся в файле Test.java, можно скомпилировать и выполнить, используя команды:
javac Test.java java Test Hello, world.
что выведет на экран:
Hello, world.
В этой спецификации мы ссылаемся на классы и интерфейсы, взятые из API платформы Java SE. Всякий раз, когда мы ссылаемся на класс или интерфейс (кроме тех, которые объявлены в примере) с помощью одного идентификатора N, предполагается ссылка на класс или интерфейс с именем N в пакете java.lang. Мы используем каноническое имя (§6.7) для классов или интерфейсов из пакетов, отличных от java.lang.
Ненормативная информация, предназначенная для разъяснения спецификации, приводится в более мелких, отстуженных текстах.
Это ненормативная информация. Она предоставляет интуицию, обоснование, рекомендации, примеры и т. д.
Система типов языка программирования Java иногда опирается на понятие подстановки. Нотация [F1:=T1,...,Fn:=Tn] обозначает подстановку Fi на Ti для 1 ≤ i ≤ n.
Как отмечалось выше, эта спецификация часто ссылается на классы API платформы Java SE. В частности, некоторые классы имеют особую связь с языком программирования Java. К таким классам относятся, например, классы Object, Class, ClassLoader, String, Thread, а также классы и интерфейсы в пакете java.lang.reflect и другие. Эта спецификация ограничивает поведение таких классов и интерфейсов, но не предоставляет полную спецификацию для них. Читатель должен обратиться к документации API платформы Java SE.
Поэтому в этой спецификации отражение не описывается подробно. Многие языковые конструкции имеют аналоги в Core Reflection API (java.lang.reflect) и Language Model API (javax.lang.model), но они обычно не обсуждаются здесь. Например, когда мы перечисляем способы создания объекта, мы обычно не включаем способы, которые может осуществить Core Reflection API. Читатели должны быть осведомлены об этих дополнительных механизмах, даже если они не упоминаются в тексте.
Читатели могут сообщать об технических ошибках и неоднозначностях в Спецификации языка программирования Java® в jls-jvms-spec-comments@openjdk.java.net.
Вопросы, касающиеся поведения javac (справочного компилятора языка программирования Java), и, в частности, его соответствия данной спецификации, могут быть отправлены в compiler-dev@openjdk.java.net.
Библиография
Apple Computer. Справочное руководство по Dylan. Apple Computer Inc., Купертино, Калифорния. 29 сентября 1995 г.
Bobrow, Daniel G., Linda G. DeMichiel, Richard P. Gabriel, Sonya E. Keene, Gregor Kiczales и David A. Moon. Спецификация системы обьектов Common Lisp, документ X3J13 88-002R, июнь 1988; публикуется как глава 28 в Steele, Guy. Common Lisp: Язык программирования, 2-е изд. Digital Press, 1990, ISBN 1-55558-041-6, 770-864.
Ellis, Margaret A. и Bjarne Stroustrup. Комментированное руководство по C++. Addison-Wesley, Ридинг, Массачусетс, 1990, перепечатано с исправлениями в октябре 1992, ISBN 0-201-51459-1.
Goldberg, Adele и Robson, David. Smalltalk-80: Язык программирования. Addison-Wesley, Ридинг, Массачусетс, 1989, ISBN 0-201-13688-0.
Harbison, Samuel. Modula-3. Prentice Hall, Энглвуд Клиффс, Нью-Джерси, 1992, ISBN 0-13-596396.
Hoare, C. A. R. Рекомендации по проектированию языков программирования. Технический отчет кафедры компьютерных наук Стэнфордского университета № CS-73-403, декабрь 1973 г. Перепечатано в Симпозиуме SIGACT/SIGPLAN по принципам языков программирования. Ассоциация вычислительной техники, Нью-Йорк, октябрь 1973 г.
Стандарт IEEE для бинарной арифметики с плавающей точкой. ANSI/IEEE Std. 754-1985. Доступен в Global Engineering Documents, 15 Inverness Way East, Энглвуд, Колорадо 80112-5704 США; 800-854-7179.
Kernighan, Brian W. и Ritchie, Dennis M. Язык программирования C, 2-е изд. Prentice Hall, Энглвуд Клиффс, Нью-Джерси, 1988, ISBN 0-13-110362-8.
Madsen, Ole Lehrmann, Birger Møller-Pedersen и Kristen Nygaard. Объектно-ориентированное программирование на языке программирования Beta. Addison-Wesley, Ридинг, Массачусетс, 1993, ISBN 0-201-62430-3.
Mitchell, James G., William Maybury и Richard Sweet. Язык программирования Mesa, версия 5.0. Xerox PARC, Пало-Альто, Калифорния, CSL 79-3, апрель 1979 г.
Stroustrup, Bjarne. Язык программирования C++, 2-е изд. Addison-Wesley, Ридинг, Массачусетс, 1991, перепечатано с исправлениями в январе 1994, ISBN 0-201-53992-6.
Консорциум Unicode. Стандарт Unicode, версия 10.0.0. Маунтин-Вью, Калифорния, 2017, ISBN 978-1-936213-16-0.
© Oracle and/or its affiliates. All rights reserved.
Licensed under the Oracle Technology Network License Agreement.