Глава 1. Введение
Оглавление
Язык программирования Java® — это универсальный, конкуретентный, основанный на классах, объектно-ориентированный язык. Он разработан достаточно простым, чтобы многие программисты смогли овладеть им. Язык программирования Java связан с C и C++, но организован несколько иначе, с исключением некоторых аспектов C и C++ и включением нескольких идей из других языков. Он предназначен для использования в производстве, а не для исследовательских целей, и, как предлагал К. А. Р. Хоар в своей классической статье по разработке языка, дизайн избегает включения новых и не проверенных функций.
Язык программирования Java — язык со строгой и статической типизацией. В данной спецификации чётко различаются ошибки времени компиляции, которые могут и должны быть обнаружены на этапе компиляции, и ошибки, возникающие во время выполнения. Компиляция обычно включает в себя перевод программ в независимую от машины байт-кодовую форму. Действия во время выполнения включают загрузку и связывание необходимых классов для выполнения программы, необязательную генерацию машинного кода и динамическую оптимизацию программы, а также фактическое выполнение программы.
Язык программирования Java — язык относительно высокого уровня, так как детали машинного представления недоступны через язык. Он включает автоматическое управление памятью, обычно с использованием сборщика мусора, чтобы избежать проблем безопасности явного освобождения памяти (как в C's free или C++'s delete). Высокопроизводительные реализации с сборщиком мусора могут иметь ограниченные паузы для поддержки системного программирования и приложений реального времени. Язык не содержит небезопасных конструкций, таких как доступ к массивам без проверки индекса, так как такие небезопасные конструкции могут привести к тому, что программа будет вести себя непредсказуемо.
Язык программирования Java обычно компилируется в набор инструкций байт-кода и бинарный формат, определённый в Спецификации виртуальной машины Java, издание Java SE 8.
В главе 2 описываются грамматики и обозначения, используемые для представления лексической и синтаксической грамматик языка.
Глава 3 описывает лексическую структуру языка программирования Java, основанную на C и C++. Язык написан в кодировке Unicode. Он поддерживает написание символов Unicode на системах, поддерживающих только ASCII.
Глава 4 описывает типы, значения и переменные. Типы подразделяются на примитивные типы и типы ссылок.
Примитивные типы определяются одинаковыми на всех машинах и во всех реализациях и представляют собой целые числа со знаком разного размера, числа с плавающей точкой одинарной и двойной точности стандарта IEEE 754, тип boolean и тип символа Unicode char. Значения примитивных типов не разделяют состояние.
Типы ссылок — это типы классов, типы интерфейсов и типы массивов. Типы ссылок реализуются динамически созданными объектами, которые являются экземплярами классов или массивов. Может существовать множество ссылок на каждый объект. Все объекты (включая массивы) поддерживают методы класса Object, который является (единственным) корнем иерархии классов. Предварительно определенный класс String поддерживает строковые представления символов Unicode. Существуют классы для обертывания примитивных значений внутри объектов. Во многих случаях обертывание и распаковку выполняет компилятор (в этом случае обертывание называется бокс-преобразованием, а распаковку — унбоксингом). Декларации классов и интерфейсов могут быть обобщенными, то есть параметризованными другими типами ссылок. Такие объявления затем могут быть вызваны со специфическими аргументами типа.
Переменные — это типизированные места хранения. Переменная примитивного типа хранит значение этого примитивного типа. Переменная типа класса может хранить нулевую ссылку или ссылку на объект, тип которого — данный тип класса или любой подтип этого класса. Переменная типа интерфейса может хранить нулевую ссылку или ссылку на экземпляр любого класса, реализующего этот интерфейс. Переменная типа массива может хранить нулевую ссылку или ссылку на массив. Переменная типа класса Object может хранить нулевую ссылку или ссылку на любой объект, будь то экземпляр класса или массив.
Глава 5 описывает преобразования и числовые продвижения. Преобразования изменяют тип выражения во время компиляции и иногда значение выражения. Эти преобразования включают преобразования бокс-преобразования и унбоксинга между примитивными типами и типами ссылок. Числовые продвижения используются для преобразования операндов числового оператора в общий тип, где можно выполнить операцию. В языке нет лазеек; приведения типов ссылок проверяются во время выполнения для обеспечения безопасности типов.
Глава 6 описывает объявления и имена и то, как определить, что означают имена (обозначают). Язык не требует объявления типов или их членов до их использования. Порядок объявления важен только для локальных переменных, локальных классов и порядка инициализаторов полей в классе или интерфейсе.
Язык программирования Java предоставляет контроль над областью видимости имен и поддерживает ограничения на внешний доступ к членам пакетов, классов и интерфейсов. Это помогает при написании больших программ, разделяя реализацию типа от его пользователей и тех, кто его расширяет. Здесь описываются рекомендуемые соглашения об именовании, которые делают программы более читабельными.
Глава 7 описывает структуру программы, организованной в пакеты, аналогичные модулям Modula. Члены пакета — это классы, интерфейсы и подпакеты. Пакеты делятся на единицы компиляции. Единицы компиляции содержат объявления типов и могут импортировать типы из других пакетов, чтобы дать им короткие имена. У пакетов есть имена в иерархическом пространстве имен, и система доменных имен интернета обычно может использоваться для создания уникальных имён пакетов.
Глава 8 описывает классы. Члены классов — это классы, интерфейсы, поля (переменные) и методы. Переменные класса существуют один раз на класс. Методы класса работают без ссылки на конкретный объект. Экземплярные переменные динамически создаются в объектах, являющихся экземплярами классов. Экземплярные методы вызываются на экземплярах классов; такие экземпляры становятся текущим объектом this во время их выполнения, поддерживая стиль объектно-ориентированного программирования.
Классы поддерживают одиночное наследование реализации, при котором реализация каждого класса происходит от реализации одного суперкласса, и, в конечном счете, от класса Object. Переменные типа класса могут ссылаться на экземпляр этого класса или любого подкласса этого класса, позволяя использовать новые типы с существующими методами полиморфно.
Классы поддерживают конкурентное программирование с использованием synchronized методов. Методы объявляют обработку исключений, которые могут возникнуть при их выполнении, что позволяет проверять во время компиляции, чтобы убедиться, что исключительные ситуации обрабатываются. Объекты могут объявлять метод finalize, который будет вызван перед тем, как объекты будут удалены сборщиком мусора, позволяя объектам очистить своё состояние.
Для простоты язык не имеет отдельных «заголовков» объявления, отличных от реализации класса, а также отдельных иерархий типов и классов.
Особая форма классов, перечисления (enums), поддерживает определение небольших наборов значений и их обработку безопасным для типа способом. В отличие от перечислений в других языках, перечисления являются объектами и могут иметь свои собственные методы.
Глава 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. Для классов или интерфейсов из пакетов, отличных от java.lang, мы используем каноническое имя (§6.7).
Ненормативная информация, предназначенная для разъяснения спецификации, приведена в более мелких, отступленных строках.
Это ненормативная информация. Она предоставляет интуицию, обоснование, рекомендации, примеры и т. д.
Система типов языка программирования 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.
Следовательно, данная спецификация не описывает рефлексию подробно. Многие языковые конструкции имеют аналоги в API Core Reflection (java.lang.reflect) и API Language Model (javax.lang.model), но они обычно здесь не рассматриваются. Например, когда мы перечисляем способы создания объекта, мы обычно не включаем способы, которые может реализовать API Core Reflection. Читатели должны быть осведомлены об этих дополнительных механизмах, даже если они не упоминаются в тексте.
Читатели могут сообщить о технических ошибках и неоднозначностях в Спецификации языка программирования 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 Object System, документ 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., и Dennis M. Ritchie. Язык программирования 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 Consortium, The. Стандарт Unicode, версия 6.2.0. Маунтин-Вью, Калифорния, 2012, ISBN 978-1-936213-07-8.
© Oracle and/or its affiliates. All rights reserved.
Licensed under the Oracle Technology Network License Agreement.