Изучите Java с нуля

Итак, вы хотите программировать на Java? Это здорово, и вы попали в нужное место. Серия Java 101 представляет собой самостоятельное введение в программирование на Java, начиная с основ и охватывая все основные концепции, которые вам нужно знать, чтобы стать продуктивным разработчиком Java. Эта серия является технической, с множеством примеров кода, которые помогут вам понять концепции по мере продвижения. Я предполагаю, что у вас уже есть некоторый опыт программирования, только не на Java.

Эта первая статья знакомит с платформой Java и объясняет разницу между ее тремя редакциями: Java SE, Java EE и Java ME. Вы также узнаете о роли виртуальной машины Java (JVM) в развертывании приложений Java. Я помогу вам установить Java Development Kit (JDK) в вашей системе, чтобы вы могли разрабатывать и запускать Java-программы, и я начну с архитектуры типичного Java-приложения. Наконец, вы узнаете, как скомпилировать и запустить простое приложение Java.

Обновлено для Java 12 и новой JShell

Эта серия была обновлена ​​для Java 12 и включает краткое введение в новое jshell: интерактивный инструмент для изучения Java и прототипирования кода Java.

загрузить Получить код Загрузите исходный код для примеров приложений из этого руководства. Создано Джеффом Фризеном для JavaWorld.

Что такое Java?

Вы можете думать о Java как о объектно-ориентированном языке общего назначения, который очень похож на C и C ++, но который проще в использовании и позволяет создавать более надежные программы. К сожалению, это определение не дает вам глубокого понимания Java. В 2000 году Sun Microsystems (создатель платформы Java) описала Java следующим образом: 

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

Рассмотрим каждое из этих определений отдельно.

Java - простой язык . Изначально Java создавалась по образцу C и C ++, за исключением некоторых потенциально сбивающих с толку функций. Указатели, множественное наследование реализаций и перегрузка операторов - это некоторые функции C / C ++, не являющиеся частью Java. Функция, не обязательная для C / C ++, но важная для Java, - это средство сбора мусора, которое автоматически освобождает объекты и массивы.

Java - объектно-ориентированный язык . Объектно-ориентированный подход Java позволяет разработчикам работать над адаптацией Java для решения проблемы, а не заставлять нас манипулировать проблемой для удовлетворения языковых ограничений. Это отличается от структурированного языка как C. В качестве примера, в то время как Java позволяет сосредоточиться на сберегательный счет объектов, C требует , чтобы вы отдельно думать о сберегательный счет государства (такой баланс) и поведение (например, ввод и вывод).

Java - язык, ориентированный на работу с сетями . Обширная сетевая библиотека Java упрощает работу с сетевыми протоколами протокола управления передачей / Интернет-протоколом (TCP / IP), такими как HTTP (протокол передачи гипертекста) и FTP (протокол передачи файлов), и упрощает задачу создания сетевых подключений. Более того, программы на Java могут получать доступ к объектам в сети TCP / IP через унифицированные указатели ресурсов (URL-адреса) с той же легкостью, что и доступ к ним из локальной файловой системы.

Java - это интерпретируемый язык . Во время выполнения программа Java косвенно выполняется на базовой платформе (например, Windows или Linux) через виртуальную машину (которая является программным представлением гипотетической платформы) и связанную среду выполнения. Виртуальная машина переводит байт-коды программы Java (инструкции и связанные данные) в инструкции для конкретной платформы посредством интерпретации. Интерпретация - это процесс выяснения того, что означает инструкция байт-кода, с последующим выбором для выполнения эквивалентных «стандартных» специфичных для платформы инструкций. Затем виртуальная машина выполняет эти специфичные для платформы инструкции.

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

Java - надежный язык . Программы на Java должны быть надежными, поскольку они используются как в потребительских, так и в критически важных приложениях, начиная от проигрывателей Blu-ray и заканчивая системами навигации или управления воздушным движением. Языковые функции, которые помогают сделать Java устойчивой, включают объявления, проверку повторяющихся типов во время компиляции и выполнения (для предотвращения проблем с несовпадением версий), истинные массивы с автоматической проверкой границ и пропуск указателей. (Чтобы начать работу с типами языка Java, литералами, переменными и т. Д., См. «Элементарные возможности языка Java».)

Другой аспект устойчивости Java заключается в том, что циклы должны управляться логическими выражениями, а не целочисленными выражениями, где 0 - ложь, а ненулевое значение - истина. Например, Java не допускает циклов в стиле C, например, while (x) x++;потому что цикл может закончиться не там, где ожидалось. Вместо этого вы должны явно указать логическое выражение, например while (x != 10) x++;(что означает, что цикл будет выполняться до тех пор, пока не будет xравно 10).

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

Теоретически Java безопасна. На практике были обнаружены и использованы различные уязвимости безопасности. В результате тогда Sun Microsystems и Oracle теперь продолжают выпускать обновления безопасности.

Java - это архитектурно-нейтральный язык . Сети соединяют платформы с разной архитектурой на основе разных микропроцессоров и операционных систем. Вы не можете ожидать, что Java будет генерировать инструкции для конкретных платформ и чтобы эти инструкции были «поняты» всеми видами платформ, которые являются частью сети. Вместо этого Java генерирует независимые от платформы инструкции байт-кода, которые легко интерпретировать для каждой платформы (посредством реализации JVM).

Java - переносимый язык . Архитектурная нейтральность способствует переносимости. Однако переносимость Java - это нечто большее, чем независимые от платформы инструкции байт-кода. Учтите, что размеры целочисленного типа не должны меняться. Например, 32-разрядный целочисленный тип всегда должен иметь знак и занимать 32 бита, независимо от того, где обрабатывается 32-разрядное целое число (например, платформа с 16-разрядными регистрами, платформа с 32-разрядными регистрами или платформа с 64-битными регистрами). Библиотеки Java также способствуют переносимости. При необходимости они предоставляют типы, которые связывают код Java с возможностями платформы наиболее переносимым способом.

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

Java - это многопоточный язык . Для повышения производительности программ, которые должны выполнять несколько задач одновременно, Java поддерживает концепцию потокового выполнения . Например, программа, которая управляет графическим интерфейсом пользователя (GUI) во время ожидания ввода от сетевого подключения, использует другой поток для выполнения ожидания вместо использования потока GUI по умолчанию для обеих задач. Это поддерживает отзывчивость графического интерфейса. Примитивы синхронизации Java позволяют потокам безопасно обмениваться данными между собой, не повреждая данные. (См. Многопоточное программирование на Java, обсуждаемое в других разделах серии статей о Java 101.)

Java - динамический язык . Поскольку взаимосвязи между программным кодом и библиотеками происходят динамически во время выполнения, нет необходимости явно связывать их. В результате, когда программа или одна из ее библиотек развивается (например, для исправления ошибок или повышения производительности), разработчику нужно только распространить обновленную программу или библиотеку. Хотя динамическое поведение приводит к меньшему количеству кода для распространения при изменении версии, эта политика распространения также может привести к конфликтам версий. Например, разработчик удаляет тип класса из библиотеки или переименовывает его. Когда компания распространяет обновленную библиотеку, существующие программы, зависящие от типа класса, выйдут из строя. Чтобы значительно уменьшить эту проблему, Java поддерживает тип интерфейса, который похож на контракт между двумя сторонами. (См. Интерфейсы, типы и другие возможности объектно-ориентированного языка, обсуждаемые в других разделах серии Java 101.)

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

Три редакции Java: Java SE, Java EE и Java ME

Sun Microsystems выпустила пакет разработки программного обеспечения Java 1.0 (JDK) в мае 1995 года. Первый JDK использовался для разработки настольных приложений и апплетов, а впоследствии Java превратилась в программирование для корпоративных серверов и мобильных устройств. Хранение всех необходимых библиотек в одном JDK сделало бы JDK слишком большим для распространения, особенно потому, что распространение в 1990-х годах было ограничено компакт-дисками небольшого размера и низкой скоростью сети. Поскольку большинству разработчиков не требовались все последние API (разработчику настольных приложений вряд ли потребуется доступ к корпоративным API Java), Sun разбила Java на три основных редакции. Со временем они стали известны как Java SE, Java EE и Java ME:

  • Платформа Java, Standard Edition (Java SE) - это платформа Java для разработки клиентских приложений (которые работают на настольных компьютерах) и апплетов (которые запускаются в веб-браузерах). Обратите внимание, что из соображений безопасности апплеты больше не поддерживаются официально.
  • Платформа Java, Enterprise Edition (Java EE ) - это платформа Java, построенная на основе Java SE, которая используется исключительно для разработки серверных приложений, ориентированных на предприятие. Серверные приложения включают сервлеты Java , которые представляют собой программы Java, похожие на апплеты, но выполняемые на сервере, а не на клиенте. Сервлеты соответствуют API сервлетов Java.
  • Платформа Java, Micro Edition (Java ME) также построена на основе Java SE. Это платформа Java для разработки мидлетов , которые представляют собой программы Java, которые работают на мобильных информационных устройствах, и Xlets , которые представляют собой программы Java, которые выполняются на встроенных устройствах.

Java SE является базовой платформой для Java и находится в центре внимания серии Java 101. Примеры кода будут основаны на самой последней версии Java на момент написания, Java 12.

Платформа Java и JVM

Java - это одновременно язык программирования и платформа для выполнения скомпилированного кода Java. Эта платформа состоит в основном из JVM, но также включает среду выполнения, которая поддерживает выполнение JVM на базовой (собственной) платформе. JVM включает несколько компонентов для загрузки, проверки и выполнения кода Java. На рисунке 1 показано, как программа Java выполняется на этой платформе. 

Джефф Фризен

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

JVM делегирует загрузку класса своему компоненту загрузчика классов. Загрузчики классов загружают файлы классов из различных источников, таких как файловые системы, сети и архивные файлы. Они изолируют JVM от сложностей загрузки классов.

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

Если байт-коды файла класса недействительны, JVM завершает работу. В противном случае его компонент интерпретатора интерпретирует байт-код по одной инструкции за раз. Интерпретация идентифицирует инструкции байт-кода и выполняет эквивалентные собственные инструкции.

Некоторые последовательности инструкций байт-кода выполняются чаще, чем другие. Когда интерпретатор обнаруживает эту ситуацию, JIT-компилятор JVM компилирует последовательность байт-кода в собственный код для более быстрого выполнения.

Во время выполнения интерпретатор обычно встречает запрос на выполнение байт-кода другого файла класса (принадлежащего программе или библиотеке). Когда это происходит, загрузчик классов загружает файл класса, а верификатор байт-кода проверяет байт-код загруженного файла класса перед его выполнением. Также во время выполнения инструкции байт-кода могут запрашивать у JVM открытие файла, отображение чего-либо на экране, создание звука или выполнение другой задачи, требующей взаимодействия с собственной платформой. JVM отвечает, используя технологию моста Java Native Interface (JNI) для взаимодействия с собственной платформой для выполнения задачи.