Введение
Язык объектно-ориентированного программирования Java — это высокоуровневый, основанный на классах, объектно-ориентированный язык программирования, разработанный с минимальным количеством зависимостей от реализации. Это язык программирования общего назначения, предназначенный для реализации принципа "написал однажды — запускай везде" (WORA), что означает, что скомпилированный код Java может выполняться на всех платформах, поддерживающих Java, без необходимости перекомпиляции. Приложения Java обычно компилируются в байт-код, который может выполняться на любой виртуальной машине Java (JVM) независимо от базовой компьютерной архитектуры. Синтаксис Java схож с C и C++, но имеет меньше низкоуровневых возможностей, чем они. Среда выполнения Java предоставляет динамические возможности (такие как рефлексия и изменение кода во время выполнения), которые обычно недоступны в традиционных компилируемых языках. Java быстро приобрела популярность после выпуска и с тех пор остается одним из самых популярных языков программирования. По данным GitHub, в 2022 году Java занимала третье место по популярности. Несмотря на широкую распространенность, в последние годы наблюдается постепенное снижение использования Java, в то время как другие языки, работающие на JVM, набирают популярность. Java была первоначально разработана Джеймсом Гослингом в Sun Microsystems и выпущена в мае 1995 года как основной компонент платформы Java от Sun. Первоначальные эталонные реализации компиляторов Java, виртуальных машин и библиотек классов были выпущены Sun под проприетарными лицензиями. С мая 2007 года, в соответствии со спецификациями Java Community Process, Sun перелицензировала большинство своих технологий Java под лицензией GPL 2.0. Oracle предлагает собственную виртуальную машину HotSpot Java, однако официальной эталонной реализацией является JVM OpenJDK, которая является бесплатным программным обеспечением с открытым исходным кодом и используется большинством разработчиков, а также является JVM по умолчанию для большинства дистрибутивов Linux. По состоянию на 2024 год Java 22 является последней версией. Java 8, 11, 17 и 21 — это предыдущие версии LTS, которые все еще официально поддерживаются.
Java is a high level, class based, object oriented programming language that is designed to have as few implementation dependencies as possible. It is a general purpose programming language intended to let programmers write once, run anywhere (WORA), meaning that compiled Java code can run on all platforms that support Java without the need to recompile. Java applications are typically compiled to bytecode that can run on any Java virtual machine (JVM) regardless of the underlying computer architecture. The syntax of Java is similar to C and C++, but has fewer low level facilities than either of them. The Java runtime provides dynamic capabilities (such as reflection and runtime code modification) that are typically not available in traditional compiled languages. Java gained popularity shortly after its release, and has been a very popular programming language since then. Java was the third most popular programming language in as of 2022 according to GitHub. Although still widely popular, there has been a gradual decline in use of Java in recent years with other languages using JVM gaining popularity. Java was originally developed by James Gosling at Sun Microsystems. It was released in May 1995 as a core component of Sun's Java platform. The original and reference implementation Java compilers, virtual machines, and class libraries were originally released by Sun under proprietary licenses. As of May 2007, in compliance with the specifications of the Java Community Process, Sun had relicensed most of its Java technologies under the GPL 2.0 only license. Oracle offers its own HotSpot Java Virtual Machine, however the official reference implementation is the OpenJDK JVM which is free open source software and used by most developers and is the default JVM for almost all Linux distributions. as of 2024, Java 22 is the latest version. Java 8, 11, 17, and 21 are previous LTS versions still officially supported.
История
Джеймс Гослинг, Майк Шеридан и Патрик Ноттон инициировали проект языка Java в июне 1991 года. Java изначально разрабатывалась для интерактивного телевидения, но в то время была слишком передовой для индустрии цифрового кабельного телевидения. Первоначально язык назывался Oak, в честь дуба, росшего возле офиса Гослинга. Позже проект получил название Green и, наконец, был переименован в Java, по названию кофейных зерен Java – сорта кофе из Индонезии. Гослинг разработал Java с синтаксисом в стиле C/C++, который был бы знаком системным и прикладным программистам. Sun Microsystems выпустила первую публичную реализацию Java 1.0 в 1996 году. Она обещала принцип "написал однажды – запускай везде" (WORA), предоставляя бесплатную среду выполнения на популярных платформах. Достаточно безопасный и с настраиваемой системой безопасности, он обеспечивал ограничения доступа к сети и файлам. Крупные веб-браузеры вскоре включили возможность запуска Java-апплетов в веб-страницах, и Java быстро стала популярной. Компилятор Java 1.0 был переписан Артуром ван Хоффом на Java, чтобы строго соответствовать спецификации языка Java 1.0. С появлением Java 2 (первоначально выпущенной как J2SE 1.2 в декабре 1998 – 1999 годов) новые версии имели несколько конфигураций, предназначенных для различных типов платформ. J2EE включал технологии и API для корпоративных приложений, обычно работающих в серверных средах, а J2ME – API, оптимизированные для мобильных приложений. Настольная версия была переименована в J2SE. В 2006 году, в маркетинговых целях, Sun переименовала новые версии J2 в Java EE, Java ME и Java SE соответственно. В 1997 году Sun Microsystems обратилась в орган по стандартизации ISO/IEC JTC 1, а затем в Ecma International, чтобы формализовать Java, но вскоре вышла из этого процесса. Java остаётся де-факто стандартом, контролируемым через Java Community Process. В свое время Sun сделала большинство своих реализаций Java доступными бесплатно, несмотря на их статус проприетарного программного обеспечения. Sun получала доход от Java за счет продажи лицензий на специализированные продукты, такие как Java Enterprise System. 13 ноября 2006 года Sun выпустила значительную часть своей виртуальной машины Java (JVM) как свободное и открытое программное обеспечение (FOSS) под лицензией GPL 2.0. 8 мая 2007 года Sun завершила процесс, сделав весь основной код своей JVM доступным на условиях распространения свободного программного обеспечения/открытого исходного кода, за исключением небольшой части кода, на которую Sun не имела авторских прав. Вице-президент Sun Рич Грин заявил, что идеальная роль Sun в отношении Java – быть её евангелистом. После приобретения Sun Microsystems корпорацией Oracle в 2009–2010 годах Oracle заявила о себе как о хранителе технологии Java с неуклонной приверженностью развитию сообщества участия и прозрачности. Это не помешало Oracle вскоре после этого подать в суд на Google за использование Java в SDK Android (см. раздел Android). 2 апреля 2010 года Джеймс Гослинг ушёл в отставку из Oracle. В январе 2016 года Oracle объявила, что среды выполнения Java, основанные на JDK 9, прекратят поддержку плагина браузера. Программное обеспечение Java работает на всем: от ноутбуков до центров обработки данных, игровых консолей и научных суперкомпьютеров. Oracle (и другие) настоятельно рекомендуют удалять устаревшие и неподдерживаемые версии Java из-за нерешенных проблем безопасности в старых версиях.
Издания
Sun определила и поддерживает четыре версии Java, предназначенные для различных областей применения, и разделила многие из своих API таким образом, что они относятся к одной из этих платформ. Эти платформы:
Java Card для смарт-карт. Java Platform, Micro Edition (Java ME) – для сред с ограниченными ресурсами. Java Platform, Standard Edition (Java SE) – для рабочих станций. Java Platform, Enterprise Edition (Java EE) – для крупных распределенных корпоративных или интернет-сред. Классы в API Java организованы в отдельные группы, называемые пакетами. Каждый пакет содержит набор связанных интерфейсов, классов, подпакетов и исключений. Sun также представила версию под названием Personal Java, которая устарела и была заменена более поздними, основанными на стандартах, сочетаниями профилей конфигураций Java ME.
Java JVM и байт-код
Одна из целей разработки Java — переносимость, что означает, что программы, написанные для платформы Java, должны работать одинаково на любой комбинации аппаратного обеспечения и операционной системы при наличии необходимой среды выполнения. Это достигается путем компиляции кода на языке Java в промежуточное представление, называемое байт-кодом Java, а не напрямую в машинный код, специфичный для конкретной архитектуры. Инструкции байт-кода Java аналогичны машинному коду, но предназначены для выполнения виртуальной машиной (VM), разработанной специально для целевого оборудования. Обычные пользователи обычно используют среду выполнения Java Runtime Environment (JRE), установленную на их устройстве, для автономных Java-приложений или веб-браузер для Java-апплетов. Стандартные библиотеки предоставляют универсальный способ доступа к функциям, специфичным для хост-системы, таким как графика, многопоточность и сетевое взаимодействие. Использование универсального байт-кода упрощает перенос. Однако накладные расходы на интерпретацию байт-кода в машинные инструкции приводят к тому, что интерпретируемые программы почти всегда работают медленнее, чем нативные исполняемые файлы. Компиляторы Just-In-Time (JIT), которые компилируют байт-код в машинный код во время выполнения, были внедрены с самого начала. Компилятор Hotspot в Java фактически состоит из двух компиляторов; а с появлением GraalVM (включенного, например, в Java 11, но удаленного начиная с Java 16) стала возможна многоуровневая компиляция. Сама Java является платформенно-независимой и адаптируется к конкретной платформе, на которой она должна выполняться, с помощью виртуальной машины Java (JVM), которая транслирует байт-код Java в машинный язык этой платформы.
Выступление
Программы, написанные на Java, имеют репутацию более медленных и требовательных к памяти, чем программы, написанные на C++. Однако скорость выполнения программ на Java значительно возросла с внедрением JIT-компиляции в 1997/1998 годах для Java 1.1, добавлением языковых средств, обеспечивающих более качественный анализ кода (таких как внутренние классы, класс StringBuilder, необязательные проверки и т. д.), а также оптимизацией в виртуальной машине Java, например, когда HotSpot стала JVM по умолчанию от Sun в 2000 году. С Java 1.5 производительность была улучшена благодаря добавлению пакета `java.util.concurrent`, включающего безблокировочные реализации ConcurrentMap и других коллекций для многоядерных процессоров, и была дополнительно улучшена с Java 1.6.
Не-ОДМ
Некоторые платформы обеспечивают прямую аппаратную поддержку Java; существуют микроконтроллеры, способные выполнять Java-байткод непосредственно на аппаратном уровне, а не с помощью программной Java-виртуальной машины, и некоторые процессоры на базе ARM могли иметь аппаратную поддержку выполнения Java-байткода благодаря опции Jazelle, хотя в современных реализациях ARM эта поддержка в основном отсутствует.
Автоматическое управление памятью
Java использует автоматический сборщик мусора для управления памятью в жизненном цикле объектов. Программист определяет, когда создаются объекты, а среда выполнения Java отвечает за освобождение памяти, когда объекты больше не используются. Как только не остаётся ссылок на объект, недоступная память становится пригодной для автоматического освобождения сборщиком мусора. Ситуация, похожая на утечку памяти, всё же может возникнуть, если код программиста удерживает ссылку на объект, который больше не нужен, обычно когда ненужные объекты хранятся в контейнерах, которые всё ещё используются. Если вызываются методы несуществующего объекта, выбрасывается исключение NullPointerException. Одна из основных идей автоматической модели управления памятью в Java заключается в том, чтобы избавить программистов от необходимости выполнять ручное управление памятью. В некоторых языках память для создания объектов неявно выделяется в стеке или явно выделяется и освобождается из кучи. В последнем случае ответственность за управление памятью лежит на программисте. Если программа не освобождает объект, происходит утечка памяти. Если программа пытается получить доступ к памяти, которая уже была освобождена, или освободить её повторно, результат непредсказуем и может привести к нестабильной работе программы или её аварийному завершению. Эту проблему можно частично решить с помощью умных указателей, но они добавляют накладные расходы и усложняют код. Сборка мусора не предотвращает логические утечки памяти, то есть случаи, когда память всё ещё ссылается, но никогда не используется. Сборка мусора может происходить в любое время. В идеале, она должна происходить, когда программа простаивает. Гарантированно, она будет запущена, если на куче недостаточно свободной памяти для выделения нового объекта; это может привести к кратковременной задержке в работе программы. Явное управление памятью невозможно в Java. Java не поддерживает арифметику указателей в стиле C/C++, где адреса объектов могут подвергаться арифметическим операциям (например, путём добавления или вычитания смещения). Это позволяет сборщику мусора перемещать объекты, на которые есть ссылки, и обеспечивает типобезопасность и безопасность. Как и в C++ и некоторых других объектно-ориентированных языках, переменные примитивных типов данных Java хранятся либо непосредственно в полях (для объектов), либо в стеке (для методов), а не в куче, как это обычно происходит с не примитивными типами данных (но см. анализ экранирования). Это было сознательным решением разработчиков Java, обусловленным соображениями производительности. Java содержит несколько типов сборщиков мусора. Начиная с Java 9, HotSpot использует Garbage First Garbage Collector (G1GC) по умолчанию. Однако существуют и другие сборщики мусора, которые можно использовать для управления кучей. Для большинства приложений на Java G1GC достаточно. Ранее в Java 8 использовался Parallel Garbage Collector. Решение проблемы управления памятью не освобождает программиста от необходимости правильно обрабатывать другие виды ресурсов, такие как сетевые или базы данных соединения, дескрипторы файлов и т. д., особенно при возникновении исключений.
Синтаксис
Синтаксис Java во многом сформирован под влиянием C++ и C. В отличие от C++, который объединяет синтаксис для структурированного, обобщенного и объектно-ориентированного программирования, Java был разработан практически исключительно как объектно-ориентированный язык. Java не поддерживает множественное наследование для классов, хотя множественное наследование поддерживается для интерфейсов. Java использует комментарии, аналогичные комментариям в C++. Существует три различных стиля комментариев: однострочный, обозначаемый двумя слешами (//), многострочный, открываемый с /* и закрываемый с */, и стиль комментариев Javadoc, открываемый с /** и закрываемый с */. Стиль комментариев Javadoc позволяет пользователю запускать исполняемый файл Javadoc для создания документации к программе, и эта документация может быть прочитана некоторыми интегрированными средами разработки (IDE), такими как Eclipse, предоставляя разработчикам доступ к документации непосредственно в IDE.
Яблочко
Java апплеты — это программы, внедряемые в другие приложения, обычно на веб-странице, отображаемой в веб-браузере. API Java апплетов устарел, начиная с Java 9 в 2017 году.
Страницы JavaServer
JavaServer Pages (JSP) — это компоненты Java EE на стороне сервера, которые генерируют ответы, как правило, HTML-страницы, на HTTP-запросы от клиентов. JSP позволяют встраивать Java-код в HTML-страницу с помощью специальных разделителей <% и %>. При первом обращении JSP компилируется в Java-сервлет — полноценное Java-приложение. После этого сгенерированный сервлет формирует ответ.
Применение колебания
Swing — это библиотека графического пользовательского интерфейса для платформы Java SE. Возможно указать отличный внешний вид и оформление с помощью подключаемой системы изменения внешнего вида Swing. Sun предоставляет клоны Windows, GTK+ и Motif. Apple также предлагает оформление Aqua для macOS. Если предыдущие реализации этих стилей могли считаться недостаточно проработанными, Swing в Java SE 6 решает эту проблему, используя более нативные процедуры отрисовки графических элементов пользовательского интерфейса базовых платформ.
Приложение JavaFX
JavaFX — это программная платформа для создания и распространения настольных приложений, а также насыщенных веб-приложений, способных работать на широком спектре устройств. JavaFX задумывался как замена Swing в качестве стандартной библиотеки графического пользовательского интерфейса для Java SE, но начиная с JDK 11 JavaFX не входит в состав основной JDK, а поставляется в виде отдельного модуля. JavaFX поддерживает настольные компьютеры и веб-браузеры в операционных системах Microsoft Windows, Linux и macOS. JavaFX не обеспечивает поддержку оформления, соответствующего стандартному внешнему виду операционных систем.
Дженерики
В 2004 году дженерики были добавлены в язык Java как часть J2SE 5.0. До появления дженериков каждая переменная должна была быть объявлена с конкретным типом. Для классов-контейнеров это создавало проблему, поскольку не было простого способа создать контейнер, который принимал бы только объекты определенных типов. Либо контейнер работал со всеми подтипами класса или интерфейса, обычно с Object, либо для каждого типа содержимого требовалось создавать отдельный класс контейнера. Дженерики позволяют выполнять проверку типов на этапе компиляции, не создавая множество классов-контейнеров с почти идентичным кодом. Помимо повышения эффективности кода, это предотвращает возникновение определенных исключений во время выполнения, выдавая ошибки на этапе компиляции. Если бы Java предотвращала все ошибки типов во время выполнения (ClassCastExceptions), она была бы типобезопасной. В 2016 году было доказано, что система типов Java является несостоятельной, так как с помощью дженериков можно создавать классы и методы, допускающие присваивание экземпляра одного класса переменной другого, не связанного с ним класса. Такой код компилируется, но приводит к исключению ClassCastException во время выполнения.
Критика
К критике Java относятся реализация обобщенных типов (generics), скорость работы, реализация арифметики с плавающей точкой и история обнаруженных уязвимостей в безопасности основной реализации Java VM – HotSpot.
Документация
Javadoc — это всеобъемлющая система документации, разработанная Sun Microsystems. Она предоставляет разработчикам структурированный способ документирования кода. Комментарии Javadoc начинаются с дополнительной звездочки, то есть ограничители — /** и */, в то время как обычные многострочные комментарии в Java ограничиваются /* и */, а однострочные комментарии начинаются с //.
Реализация
Корпорация Oracle владеет официальной реализацией платформы Java SE в связи с приобретением Sun Microsystems 27 января 2010 года. Эта реализация основана на оригинальной реализации Java, разработанной Sun. Реализация Oracle доступна для Windows, macOS, Linux и Solaris. Поскольку Java не имеет формальной стандартизации, признанной Ecma International, ISO/IEC, ANSI или другими сторонними организациями по стандартизации, реализация Oracle является де-факто стандартом. Реализация Oracle поставляется в двух различных дистрибутивах: Java Runtime Environment (JRE), содержащая части платформы Java SE, необходимые для запуска Java-программ и предназначенная для конечных пользователей, и Java Development Kit (JDK), предназначенная для разработчиков программного обеспечения и включающая инструменты разработки, такие как компилятор Java, Javadoc, Jar и отладчик. Oracle также выпустила GraalVM – высокопроизводительный динамический компилятор и интерпретатор Java. OpenJDK – это еще одна реализация Java SE, лицензируемая под GNU GPL. Разработка OpenJDK началась, когда Sun начала публиковать исходный код Java под лицензией GPL. Начиная с Java SE 7, OpenJDK является официальной эталонной реализацией Java. Цель Java – обеспечить совместимость всех реализаций Java. Исторически, лицензионное соглашение Sun на использование торговой марки Java требовало совместимости всех реализаций. Это привело к судебному разбирательству с Microsoft после того, как Sun заявила, что реализация Microsoft не поддерживает удаленный вызов методов Java (RMI) или Java Native Interface (JNI) и добавила собственные платформенно-зависимые функции. Sun подала в суд в 1997 году и в 2001 году выиграла мировое соглашение на 20 миллионов долларов США, а также судебный приказ, обеспечивающий соблюдение условий лицензии Sun. В результате Microsoft больше не поставляет Java вместе с Windows. Платформенная независимость Java необходима для Java EE, и для сертификации реализации требуется еще более строгая проверка. Эта среда позволяет создавать переносимые серверные приложения.
Использование вне платформы Java
Язык программирования Java требует наличия программной платформы для запуска скомпилированных программ. Oracle предоставляет платформу Java для работы с Java. Android SDK является альтернативной программной платформой, используемой главным образом для разработки приложений для Android со своей собственной системой графического интерфейса.
Android
Язык Java является ключевым элементом Android, мобильной операционной системы с открытым исходным кодом. Хотя Android, основанный на ядре Linux, в основном написан на C, Android SDK использует язык Java как основу для Android-приложений, но не использует какие-либо из его стандартных графических интерфейсов, SE, ME или других устоявшихся стандартов Java. Язык байт-кода, поддерживаемый Android SDK, несовместим с байт-кодом Java и выполняется на собственной виртуальной машине, оптимизированной для устройств с ограниченной памятью, таких как смартфоны и планшетные компьютеры. В зависимости от версии Android, байт-код либо интерпретируется виртуальной машиной Dalvik, либо компилируется в машинный код средой выполнения Android (Android Runtime). Android не предоставляет полную стандартную библиотеку Java SE, хотя Android SDK включает в себя независимую реализацию значительной её части. Он поддерживает Java 6 и некоторые возможности Java 7, предлагая реализацию, совместимую со стандартной библиотекой (Apache Harmony).
Противоречия
Использование технологий, связанных с Java, в Android привело к судебному спору между Oracle и Google. 7 мая 2012 года присяжные в Сан-Франциско установили, что если API подлежат охране авторским правом, то Google нарушил авторские права Oracle, используя Java в устройствах Android. Окружной судья Уильям Алсуп 31 мая 2012 года постановил, что API не могут быть защищены авторским правом, однако это решение было отменено Апелляционным судом США по федеральному округу в мае 2014 года. 26 мая 2016 года районный суд вынес решение в пользу Google, признав использование Java API в Android добросовестным использованием. В марте 2018 года это решение было отменено Апелляционным судом, который направил дело об определении размера ущерба в федеральный суд Сан-Франциско. В январе 2019 года Google подал прошение о выдаче сертификата на рассмотрение дела в Верховный суд США, чтобы оспорить два решения Апелляционного суда, вынесенные в пользу Oracle. 5 апреля 2021 года суд вынес решение 6–2 в пользу Google, признав его использование Java API добросовестным использованием. Однако суд отказался выносить решение о возможности охраны авторским правом API, предпочтя рассматривать API Java как охраняемые авторским правом "исключительно в целях аргументации".