7 ответов

Концептуальная разница проста:

    Декларация: вы заявляете, что что-то существует, например, класс, функция или переменная. Вы не говорите ничего о том, как выглядит этот класс или функция, вы просто говорите, что он существует.

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

В Java разница между ними невелика, и формально говоря, объявление включает не только идентификатор, но и его определение. Вот как я лично подробно интерпретирую термины:

    Классы . Java действительно не разделяет декларации и определения, как это делает C/С++ (в файлах заголовка и cpp). Вы определяете их в том месте, где вы их объявляете.

    Функции . Когда вы пишете интерфейс (или абстрактный класс), вы можете сказать, что вы объявляете функцию, не определяя ее. Обычные функции, однако, всегда определяются прямо там, где они объявлены. Если хотите, смотрите тело функции как свое определение.

    Переменные . Объявление переменной может выглядеть следующим образом:

    (вы заявляете, что существует переменная x и имеет тип int), если она является локальной переменной или членом. В Java нет информации о x для определения, кроме возможных значений, которые она должна содержать, которая определяется назначением для нее.

Вот краткий обзор того, как я использую термины:

Abstract class SomeClass { // class decl. // \ int x; // variable decl. | // | public abstract void someMethod(); // function decl. | // | public int someOtherMethod() { // function decl. | // | class if (Math.random() > .5) // \ | def. return x; // | function definition | else // | | return -x; // / | // | } // | } // /

Спецификация языка Java задает и использует термин "объявление" широко, но не использует "определение" , кроме как нормальное английское слово.

Мое свидетельство заключается в том, что термин "декларация" появляется несколько раз в таблице содержания JLS и индексе, но слово "определение" также не отображается.

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

В последнем случае они могут означать то же, что и технический термин "декларация" , или они могут означать что-то другое. И если они означают что-то еще, вам нужно спросить их, что они означают. Если они определили его... достаточно справедливым, но это не стандартная терминология.

Ответы, в которых говорится, что "определение" относится к точке, в которой инициализируется переменная, специально не поддерживаются... в контексте Java. В Java инициализация переменной происходит либо в точке объявления, либо в более позднем назначении. В последнем случае специальный термин не используется... или нужен... кроме назначения и/или инициализации. Нет указанной точки, в которой хранилище выделяется для переменной. В самом деле, есть вероятность, что пространство для самой переменной выделено до , объявление будет достигнуто.

Причина, по которой термин "декларация" не используется в Java в спецификации JLS, заключается в том, что он не нужен.

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

(Единственное место в Java, где они могли использовать объявление в сравнении с определением, - это абстрактные методы. За исключением того, что если бы они это сделали, ему пришлось бы ссылаться на объявление обычного метода как на определение... для согласованности. и это будет путать, поэтому они просто называют "абстрактный" подзаголовок декларацией абстрактного метода.)

C и С++ обрабатывают эти вещи по-разному и, следовательно, в своих технических описаниях требуются разные термины "объявление" и "определение" . Я принимаю определения "Глоссарий Солнца": они C/С++ -центрические.

декларация: Оператор, который устанавливает идентификатор и связывает с ним атрибуты без необходимости резервирования его хранилища (для данных) или обеспечения реализации (для методов).

определение: Объявление, которое резервирует хранилище (для данных) или обеспечивает реализацию (для методов).

То, как я читаю глоссарий Sun, будет следующим:

List i; // declaration - variable on the stack i = new ArrayList(); // definition - gives variable a reference

1. Декларация означает создание a primitive or Object reference variable , но без присвоения значения или объекта соответственно.

, например:

Int x; // declaration of x of type int Cat myCat; // declaration of myCat an Object of type Cat

2. Defination - это когда мы присваиваем им значения или объект.

Int x = 5; Cat myCat = new Cat();

3. В случае метода, как это...

Public abstract void go(); // Method Declaration (Abstract method) public void go(){ // Method Defination // Your code }

Я думаю, что я могу лучше объяснить этот вопрос, например.

Java предоставляет богатый набор операторов для управления переменными. Все операторы Java можно разделить на следующие группы:

Арифметические операторы

Арифметические операторы - используются в математических выражениях таким же образом, как они используются в алгебре. Предположим, целая переменная A равна 10, а переменная B равна 20. В следующей таблице перечислены арифметические операторы в Java:

Пример

Следующий простой пример показывает программно арифметические операторы. Скопируйте и вставьте следующий java-код в файл test.java, скомпилируйте и запустить эту программу:

Public class Test { public static void main(String args) { int a = 10; int b = 20; int c = 25; int d = 25; System.out.println("a + b = " + (a + b)); System.out.println("a - b = " + (a - b)); System.out.println("a * b = " + (a * b)); System.out.println("b / a = " + (b / a)); System.out.println("b % a = " + (b % a)); System.out.println("c % a = " + (c % a)); System.out.println("a++ = " + (a++)); System.out.println("b-- = " + (a--)); // Проверьте разницу в d++ и ++d System.out.println("d++ = " + (d++)); System.out.println("++d = " + (++d)); } }

A + b = 30 a - b = -10 a * b = 200 b / a = 2 b % a = 0 c % a = 5 a++ = 10 b-- = 11 d++ = 25 ++d = 27

Операторы сравнения

Есть следующие операторы сравнения, поддерживаемые на языке Java. Предположим, переменная A равна 10, а переменная B равна 20. В следующей таблице перечислены реляционные операторы или операторы сравнения в Java:

Оператор Описание Пример
== Проверяет, равны или нет значения двух операндов, если да, то условие становится истинным (A == B) - не верны
!= Проверяет, равны или нет значения двух операндов, если значения не равны, то условие становится истинным (A != B) - значение истинна
> Проверяет, является ли значение левого операнда больше, чем значение правого операнда, если да, то условие становится истинным (A > B) - не верны
Проверяет, является ли значение левого операнда меньше, чем значение правого операнда, если да, то условие становится истинным (A
>= Проверяет, является ли значение левого операнда больше или равно значению правого операнда, если да, то условие становится истинным (A >= B) - значение не верны
Проверяет, если значение левого операнда меньше или равно значению правого операнда, если да, то условие становится истинным (A

Пример

Следующий простой пример показывает, программно операторы сравнения в Java. Скопируйте и вставьте следующий java-код в файл test.java, скомпилируйте и запустить эту программу:

Public class Test { public static void main(String args) { int a = 10; int b = 20; System.out.println("a == b = " + (a == b)); System.out.println("a != b = " + (a != b)); System.out.println("a > b = " + (a > b)); System.out.println("a = a = " + (b >= a)); System.out.println("b

A == b = false a != b = true a > b = false a = a = true b

Побитовые операторы

Java определяет несколько побитовых операторов, которые могут быть применены для целочисленных типов: int, long, short, char и byte. В Java побитовый оператор работает над битами и выполняет операцию бит за битом. Предположим, если a = 60; и b = 13; то в двоичном формате они будут следующие:

a = 0011 1100
b = 0000 1101
-----------------
a&b = 0000 1100
a|b = 0011 1101
a^b = 0011 0001
~a = 1100 0011

Предположим целочисленные переменная A равна 60, а переменная B равна 13. В следующей таблице перечислены побитовые операторы в Java:

Оператор Описание Пример
& (побитовое и) Бинарный оператор AND копирует бит в результат, если он существует в обоих операндах. (A & B) даст 12, который является 0000 1100
| (побитовое или) Бинарный оператор OR копирует бит, если он существует в любом из операндов. (A | B) даст 61 который равен 0011 1101
^ (побитовое логическое или) Бинарный оператор XOR копирует бит, если он установлен в одном операнде, но не в обоих. (A ^ B) даст 49, которая является 0011 0001
~ (побитовое дополнение) Бинарный оператор дополнения и имеет эффект «отражения» бит. (~ A) даст -61, которая является формой дополнением 1100 0011 в двоичной записи
Бинарный оператор сдвига влево. Значение левых операндов перемещается влево на количество бит, заданных правым операндом. A
>> (сдвиг вправо) Бинарный оператор сдвига вправо. Значение правых операндов перемещается вправо на количество бит, заданных левых операндом. A >> 2 даст 15, который является 1111
>>> (нулевой сдвиг вправо) Нулевой оператор сдвига вправо. Значение левых операндов перемещается вправо на количество бит, заданных правым операндом, а сдвинутые значения заполняются нулями. A >>> 2 даст 15, который является 0000 1111

Пример

Следующий простой пример показывает, программно побитовые операторы в Java. Скопируйте и вставьте следующий java-код в файл test.java, скомпилируйте и запустить эту программу:

Public class Test { public static void main(String args) { int a = 60; /* 60 = 0011 1100 */ int b = 13; /* 13 = 0000 1101 */ int c = 0; c = a & b; /* 12 = 0000 1100 */ System.out.println("a & b = " + c); c = a | b; /* 61 = 0011 1101 */ System.out.println("a | b = " + c); c = a ^ b; /* 49 = 0011 0001 */ System.out.println("a ^ b = " + c); c = ~a; /*-61 = 1100 0011 */ System.out.println("~a = " + c); c = a > 2; /* 215 = 1111 */ System.out.println("a >> 2 = " + c); c = a >>> 2; /* 215 = 0000 1111 */ System.out.println("a >>> 2 = " + c); } }

Будет получен следующий результат:

A & b = 12 a | b = 61 a ^ b = 49 ~a = -61 a > 15 a >>> 15

Логические операторы

Предположим, логическая переменная A имеет значение true, а переменная B хранит false. В следующей таблице перечислены логические операторы в Java:

Пример

Public class Test { public static void main(String args) { boolean a = true; boolean b = false; System.out.println("a && b = " + (a&&b)); System.out.println("a || b = " + (a||b)); System.out.println("!(a && b) = " + !(a && b)); } }

Это произведет следующий результат:

A && b = false a || b = true !(a && b) = true

Операторы присваивания

Существуют следующие операторы присваивания, поддерживаемые языком Java:

Оператор Описание Пример
= Простой оператор присваивания, присваивает значения из правой стороны операндов к левому операнду C = A + B, присвоит значение A + B в C
+= Оператор присваивания «Добавления», он присваивает левому операнду значения правого C += A, эквивалентно C = C + A
-= Оператор присваивания «Вычитания», он вычитает из правого операнда левый операнд C -= A, эквивалентно C = C - A
*= Оператор присваивания «Умножение», он умножает правый операнд на левый операнд C * = A эквивалентно C = C * A
/= Оператор присваивания «Деление», он делит левый операнд на правый операнд C /= A эквивалентно C = C / A
%= Оператор присваивания «Модуль», он принимает модуль, с помощью двух операндов и присваивает его результат левому операнду C %= A, эквивалентно C = C % A
Оператор присваивания «Сдвиг влево» C
>>= Оператор присваивания «Сдвиг вправо» C >>= 2, это как C = C >> 2
&= Оператор присваивания побитового «И» («AND») C &= 2, это как C = C & 2
^= Оператор присваивания побитового исключающего «ИЛИ» («XOR») C ^= 2, это как C = C ^ 2
|= Оператор присваивания побитового «ИЛИ» («OR») C |= 2, это как C = C | 2

Пример

Следующий простой пример показывает, программно логические операторы в Java. Скопируйте и вставьте следующий java-код в файл test.java, скомпилируйте и запустить эту программу:

Public class Test { public static void main(String args) { int a = 10; int b = 20; int c = 0; c = a + b; System.out.println("c = a + b = " + c); c += a ; System.out.println("c += a = " + c); c -= a ; System.out.println("c -= a = " + c); c *= a ; System.out.println("c *= a = " + c); a = 10; c = 15; c /= a ; System.out.println("c /= a = " + c); a = 10; c = 15; c %= a ; System.out.println("c %= a = " + c); c >= 2 ; System.out.println("c >>= 2 = " + c); c >>= 2 ; System.out.println("c >>= a = " + c); c &= a ; System.out.println("c &= 2 = " + c); c ^= a ; System.out.println("c ^= a = " + c); c |= a ; System.out.println("c |= a = " + c); } }

Будет получен следующий результат:

C = a + b = 30 c += a = 40 c -= a = 30 c *= a = 300 c /= a = 1 c %= a = 5 c >= 2 = 5 c >>= 2 = 1 c &= a = 0 c ^= a = 10 c |= a = 10

Прочие операторы

Есть несколько других операторов, поддерживаемых языком Java.

Тернарный оператор или условный оператор (?:)

Тернарный оператор - оператор, который состоит из трех операндов и используется для оценки выражений типа boolean. Тернарный оператор в Java также известен как условный оператор. Этот. Цель тернарного оператора или условного оператора заключается в том, чтобы решить, какое значение должно быть присвоено переменной. Оператор записывается в виде:

Переменная x = (выражение) ? значение if true: значение if false

Пример

Ниже приведен пример:

Public class Test { public static void main(String args){ int a , b; a = 10; b = (a == 1) ? 20: 30; System.out.println("Значение b: " + b); b = (a == 10) ? 20: 30; System.out.println("Значение b: " + b); } }

Будет получен следующий результат:

Значение b: 30 Значение b: 20

Оператор instanceof

Оператор instanceof - проверяет, является ли объект определенного типа (типа класса или типа интерфейса) и используется только для переменных ссылочного объекта. Оператор instanceof записывается в виде:

(Переменная ссылочного объекта) instanceof (класс/тип интерфейса)

Примеры

Если переменная ссылочного объекта в левой части оператора проходит проверку для класса/типа интерфейса на правой стороне, результатом будет значение true. Ниже приведен пример и описание оператора instanceof:

Public class Test { public static void main(String args){ String name = "Олег"; // Следующее вернётся верно, поскольку тип String boolean result = name instanceof String; System.out.println(result); } }

Будет получен следующий результат:

Этот оператор по-прежнему будет возвращать значение true, если сравниваемый объект является совместимым с типом на право назначения. Ниже приводится еще один пример:

Class Vehicle {} public class Car extends Vehicle { public static void main(String args){ Vehicle a = new Car(); boolean result = a instanceof Car; System.out.println(result); } }

Будет получен следующий результат:

Приоритет операторов в Java

Приоритет операторов определяет группирование терминов в выражении. Это влияет как вычисляется выражение. Некоторые операторы имеют более высокий приоритет, чем другие; например оператор умножения имеет более высокий приоритет, чем оператор сложения:

Например, x = 7 + 3 * 2. Здесь x присваивается значение 13, не 20, потому что оператор «*» имеет более высокий приоритет, чем «+», так что сначала перемножается «3 * 2», а затем добавляется «7».

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

Категория Оператор Ассоциативность
Постфикс () . (точка) Слева направо
Унарный ++ - - ! ~ Справа налево
Мультипликативный * / % Слева направо
Аддитивный + - Слева направо
Сдвиг >> >>> Слева направо
Реляционный > >= Слева направо
Равенство == != Слева направо
Побитовое «И» («AND») & Слева направо
Побитовое исключающее «ИЛИ» («XOR») ^ Слева направо
Побитовое «ИЛИ» («OR») | Слева направо
Логическое «И» («AND») && Слева направо
Логическое «ИЛИ» («OR») || Слева направо
Условный ?: Справа налево
Присваивание = += -= *= /= %= >>= Справа налево
Запятая , Слева направо

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

  1. Массив не является экземпляром какого-либо класса, указанного в дереве классов, однако каждый массив является объектом и наследуется непосредственно от java.util.Object
(new int) instanceof Object // -> evaluates to true
  1. Класс java.util.Arrays является вспомогательным классом, и массивы не являются экземплярами этого класса.
(new int) instanceof java.util.Arrays // -> compile error
  1. Класс java.lang.reflect.Array является вспомогательным классом, и массивы не являются экземплярами этого класса.
(new int) instanceof java.lang.reflect.Array // -> compile error

    Массивы наследуют все члены java.lang.Object

    Массивы переопределяют метод clone() унаследованный от Object .

    Массивы реализуют length поля, которая содержит количество компонентов массива. длина может быть положительной или нулевой. Это public и final .

    Массивы реализуют интерфейсы Cloneable и java.io.Serializable .

    Объект является экземпляром класса или массивом.

    Экземпляр класса явно создается выражением создания экземпляра класса.

    Массив явно создается выражением создания массива.

  • Этот класс содержит различные методы для работы с массивами (такие как сортировка и поиск)

    Прямой суперкласс типа массива - Object .

    Каждый тип массива реализует интерфейсы Cloneable и java.io.Serializable .

Членами типа массива являются все следующие:

    Публичная конечная length поля, которая содержит количество компонентов массива. длина может быть положительной или нулевой.

    Открытый метод clone , который переопределяет метод с тем же именем в классе Object и не выдает никаких проверенных исключений. Тип возврата метода clone типа массива T - T .

    Клон многомерного массива неглубокий, то есть он создает только один новый массив. Подмассивы являются общими.

    Все члены унаследованы от класса Object; единственный метод Object, который не наследуется, это его метод клонирования.

, Scala , Python , BeanShell , Kotlin , Gentee

Лицензия GNU General Public License / Java Community Process Сайт java.com

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

Часто к недостаткам концепции виртуальной машины относят снижение производительности. Ряд усовершенствований несколько увеличил скорость выполнения программ на Java:

  • применение технологии трансляции байт-кода в машинный код непосредственно во время работы программы (JIT -технология) с возможностью сохранения версий класса в машинном коде,
  • широкое использование платформенно-ориентированного кода (native-код) в стандартных библиотеках,
  • аппаратные средства, обеспечивающие ускоренную обработку байт-кода (например, технология Jazelle , поддерживаемая некоторыми процессорами фирмы ARM).

По данным сайта shootout.alioth.debian.org, для семи разных задач время выполнения на Java составляет в среднем в полтора-два раза больше, чем для C/C++, в некоторых случаях Java быстрее, а в отдельных случаях в 7 раз медленнее . С другой стороны, для большинства из них потребление памяти Java-машиной было в 10-30 раз больше, чем программой на C/C++. Также примечательно исследование, проведённое компанией Google , согласно которому отмечается существенно более низкая производительность и бо́льшее потребление памяти в тестовых примерах на Java в сравнении с аналогичными программами на C++ .

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

История версий

JDK 1.0

Разработка Java началась в 1990 году, первая официальная версия - Java 1.0, - была выпущена только 21 января 1996 года. Кодовое имя Oak.

JDK 1.1

  • Библиотека Accessibility.
  • Java 2D.
  • Поддержка технологии drag-and-drop .
  • Полная поддержка Unicode , включая поддержку ввода на японском, китайском и корейском языках.
  • Поддержка воспроизведения аудиофайлов нескольких популярных форматов.
  • Полная поддержка технологии CORBA .
  • JIT-компилятор, улучшенная производительность.
  • Усовершенствования инструментальных средств JDK, в том числе поддержка профилирования Java-программ.

J2SE 1.2

Дата выпуска 8 декабря 1998 года. Кодовое имя Playground. В данном случае встречается путаница. Выпускались книги, например, Beginning Java 2 by Ivor Horton (Mar 1999), фактически по J2SE 1.2 (бывшее название - Java 2). Вместе с тем по сей день такие книги публикуются, например: Х. М. Дейтел, П. Дж. Дейтел, С. И. Сантри. Технологии программирования на Java 2. Распределённые приложения (2011).

В то время, когда, как известно, Java 2 была исторически заменена следующими релизами, подобные названия книг дезориентируют в понимании, о какой же версии Java они написаны на самом деле. Если J2SE 1.2 принято считать за Java 2, а авторы книг за Java 2 принимают JDK 7, это приводит к полной путанице.

J2SE 1.3

J2SE 1.4

J2SE 5.0

Спецификация Java 5.0 была выпущена 30 сентября 2004 года, кодовое имя Tiger. C этой версии изменена официальная индексация, вместо Java 1.5 правильнее называть Java 5.0. Внутренняя же индексация Sun осталась прежней - 1.x. Минорные изменения теперь включаются без изменения индексации, для этого используется слово «Update» или буква «u», например, Java Development Kit 5.0 Update 22. Предполагается, что в обновления могут входить как исправления ошибок, так и небольшие добавления в API, JVM.

В данной версии разработчики внесли в язык целый ряд принципиальных дополнений:

  • Перечислимые типы (англ. enum ). Ранее отсутствовавшие в Java типы оформлены по аналогии с C++ , но при этом имеют ряд дополнительных возможностей.
    • Перечислимый тип является полноценным классом Java, то есть может иметь конструктор, поля, методы, в том числе скрытые и абстрактные.
    • Перечисление может реализовывать интерфейсы .
    • Для перечислений имеются встроенные методы, дающие возможность получения значений типа по имени, символьных значений, соответствующих именам, преобразования между номером и значением, проверки типа на то, что он является перечислимым.
  • Аннотации - возможность добавления в текст программы метаданных, не влияющих на выполнение кода, но допускающих использование для получения различных сведений о коде и его исполнении. Одновременно выпущен инструментарий для использования аннотированного кода. Одно из применений аннотаций - упрощение создания тестовых модулей для Java-кода.
  • Средства обобщённого программирования (англ. generics ) - механизм, аналогичный Eiffel (позже также появились и в C#, принципиально отличаются от шаблонов C++), дающий возможность создавать классы и методы с полями и параметрами произвольного объектного типа. С использованием данного механизма реализованы новые версии коллекций стандартной библиотеки Java.
  • Методы с неопределённым числом параметров.
  • Autoboxing/Unboxing - автоматическое преобразование между скалярными типами Java и соответствующими типами-обёртками (например, между int - Integer). Наличие такой возможности сокращает код, поскольку исключает необходимость выполнения явных преобразований типов в очевидных случаях.
  • Разрешён импорт статических полей и методов.
  • В язык введён цикл по коллекции объектов (итератор, англ. foreach ).
  • Было введено использование Javadoc -комментариев, которые используются для автоматического оформления документации по комментариям в исходном коде.

Java SE 6

Релиз версии состоялся 11 декабря 2006 года, кодовое имя Mustang. Изменена официальная индексация - вместо ожидаемой 6.0 версия значится как 6. Минорные изменения, как и в Java 5.0, вносятся в обычные обновления версии, например, Java Standard Edition Development Kit 6 Update 27. Внесены следующие изменения:

Java FX

Java ME Embedded

Java SE 7

Релиз версии состоялся 28 июля 2011 года, кодовое имя Dolphin . В финальную версию Java Standard Edition 7 не были включены все ранее запланированные изменения. Согласно плану развития (план «Б») , включение нововведений будет разбито на две части: Java Standard Edition 7 (без лямбда-исчисления , проекта Jigsaw, и части улучшений Coin) и Java Standard Edition 8 (все остальное), намеченный на конец 2012 года.

В новой версии, получившей название Java Standard Edition 7 (Java Platform, Standard Edition 7), помимо исправления большого количества ошибок, было представлено несколько новшеств. Так, например, в качестве эталонной реализации Java Standard Edition 7 использован не проприетарный пакет JDK , а его открытая реализация OpenJDK , а сам релиз новой версии платформы готовился при тесном сотрудничестве инженеров Oracle с участниками мировой экосистемы Java, комитетом JCP (Java Community Process) и сообществом OpenJDK . Все поставляемые Oracle бинарные файлы эталонной реализации Java Standard Edition 7 собраны на основе кодовой базы OpenJDK , сама эталонная реализация полностью открыта под лицензией GPLv2 с исключениями GNU ClassPath, разрешающими динамическое связывание с проприетарными продуктами. К другим нововведениям относится интеграция набора небольших языковых улучшений Java, развиваемых в рамках проекта Coin, добавлена поддержка языков программирования с динамической типизацией, таких, как Ruby , Python и JavaScript , поддержка загрузки классов по URL , обновлённый XML -стек, включающий JAXP 1.4, JAXB 2.2a и JAX-WS 2.2 и другие .

За 5 дней до выхода релиза Java Standard Edition 7 было обнаружено несколько серьёзных ошибок в горячей оптимизации циклов, которая включена по умолчанию и приводит виртуальную машину Java к краху. Специалисты Oracle найденные ошибки за столь короткий срок исправить не могли, но пообещали, что они будут исправлены во втором обновлении (Java 7 Update 2) и частично в первом .

Список нововведений

Java SE 8

Список нововведений

  • Полноценная поддержка лямбда-выражений .
  • Ключевое слово default в интерфейсах для поддержки функциональности по умолчанию.
  • Ссылки на методы.
  • Функциональные интерфейсы (предикаты , поставщики и т. д.)
  • Потоки (stream) для работы с коллекциями
  • Новое API для работы с датами
  • … (не закончено)

Java SE 9

Список нововведений

  • Интеграция jigsaw.
  • Обновление Process API для лучшего взаимодействия с не-Java процессами операционной системы.
  • Новый HTTP-клиент с поддержкой HTTP 2.0, веб-сокетов и заменой устаревшему HttpURLConnection.
  • Новый компилятор "Graal"
  • Сжатые строки
  • Java Microbenchmark Harness (JMH)
  • ...(не закончено)

Классификация платформ Java

Внутри Java существует несколько основных семейств технологий:

  • Java SE - Java Standard Edition, основное издание Java, содержит компиляторы, API, Java Runtime Environment ; подходит для создания пользовательских приложений, в первую очередь - для настольных систем.
  • Java EE - Java Enterprise Edition, представляет собой набор спецификаций для создания программного обеспечения уровня предприятия.
  • Java ME - Java Micro Edition, создана для использования в устройствах, ограниченных по вычислительной мощности, например, в мобильных телефонах , КПК , встроенных системах;
  • JavaFX - технология, являющаяся следующим шагом в эволюции Java как Rich Client Platform; предназначена для создания графических интерфейсов корпоративных приложений и бизнеса.
  • Java Card - технология предоставляет безопасную среду для приложений, работающих на смарт-картах и других устройствах с очень ограниченным объёмом памяти и возможностями обработки.

Java и Microsoft

В 2005 году компанией Microsoft для платформы .NET был представлен Java-подобный язык , не соответствующий официальной спецификации языка Java и исключённый впоследствии из стандартного инструментария разработчика Microsoft Visual Studio , начиная с Visual Studio 2008 .

Java и Android

Язык Java активно используется для создания мобильных приложений под операционную систему Android. При этом программы компилируются в нестандартный байт-код, для использования их виртуальной машиной Dalvik (начиная с Android 5.0 Lollipop виртуальная машина заменена на ART). Для такой компиляции используется дополнительный инструмент, а именно Android SDK (Software Development Kit), разработанный компанией Google .

Разработку приложений можно вести в среде Android Studio , NetBeans , в среде Eclipse , используя при этом плагин Android Development Tools (ADT), или в IntelliJ IDEA . Версия JDK при этом должна быть 5.0 или выше.

Следующие компании в основном фокусируются на Java (J2EE) технологиях: SAP , IBM , Oracle . В частности, СУБД Oracle Database включает JVM как свою составную часть, обеспечивающую возможность непосредственного программирования СУБД на языке Java, включая, например, хранимые процедуры .

Производительность

Программы, написанные на Java, имеют репутацию более медленных и занимающих больше оперативной памяти, чем написанные на языке C . Тем не менее, скорость выполнения программ, написанных на языке Java, была существенно улучшена с выпуском в 1997-1998 годах так называемого JIT-компилятора в версии 1.1 в дополнение к другим особенностям языка для поддержки лучшего анализа кода (такие, как внутренние классы, класс StringBuffer, упрощенные логические вычисления и т. д.). Кроме того, была произведена оптимизация виртуальной машины Java - с 2000 года для этого используется виртуальная машина HotSpot . По состоянию на февраль 2012 года, код Java 7 приблизительно в 1.8 раза медленнее кода, написанного на языке Си .

Некоторые платформы предлагают аппаратную поддержку выполнения для Java [ ] . К примеру, микроконтроллеры, выполняющие код Java на аппаратном обеспечении вместо программной JVM, а также основанные на ARM процессоры, которые поддерживают выполнение байткода Java через опцию Jazelle.

Основные возможности

Внутри пакета есть два независимых пространства имен: переменные и методы.

Пример программы

Пример использования Generics

import java.util.* ; public class Sample { public static void main (String args ) { // Создание объекта по шаблону. List < String > strings = new LinkedList < String >(); strings . add ("Hello" ); strings . add ("world" ); strings . add ("!" ); for (String s : strings ) { System . out . print (s + " " ); } } }

Пример использования Reflection

import java.lang.reflect.Field ; import java.lang.reflect.Method ; class TestClass { private int value ; public int getValue () { return value ; } public void setValue (int valueIn ) { this . value = valueIn ; } } public class Main { public static void main (String args ) { TestClass testClass = new TestClass (); for (Field field : testClass . getClass (). getDeclaredFields ()) { System . out . printf ("name:%s, type:%s \n" , field . getName (), field . getType (). getCanonicalName ()); } for (Method method : testClass . getClass (). getDeclaredMethods ()) { System . out . printf ("name:%s, return type:%s \n" , method . getName (), method . getReturnType (). getCanonicalName ()); } } }

Пример использования Аннотаций

import java.lang.annotation.ElementType ; import java.lang.annotation.Retention ; import java.lang.annotation.RetentionPolicy ; import java.lang.annotation.Target ; @Retention (RetentionPolicy . RUNTIME ) @Target (ElementType . TYPE ) public @interface Annotation { public boolean value () default false ; } @Annotation (value = true ) public class TestClass { } public class Main { public static void main (String args ) { TestClass testClass = new TestClass (); Annotation annotation = testClass . getClass (). getAnnotation (Annotation . class ); if (annotation != null ) { System . out . printf ("value:%s \n" , annotation . value ()); } } }

Основные идеи

Примитивные типы

В языке Java только 8 примитивных (скалярных, простых) типов : boolean , byte , char , short, int , long, float , double . Существует также вспомогательный девятый примитивный тип - void , однако переменные и поля такого типа не могут быть объявлены в коде, а сам тип используется только для описания соответствующего ему класса, для использования при рефлексии : например, с помощью класса Void можно узнать, является ли определённый метод типа void: Hello.class.getMethod("main", String.class).getReturnType() == Void.TYPE .

Длины и диапазоны значений примитивных типов определяются стандартом, а не реализацией, и приведены в таблице. Тип char сделали двухбайтовым для удобства локализации (один из идеологических принципов Java): когда складывался стандарт, уже существовал Unicode -16, но не Unicode-32. Поскольку в результате не осталось однобайтового типа, добавили новый тип byte, причём в Java, в отличие от других языков, он не является беззнаковым. Типы float и double могут иметь специальные значения + ∞ {\displaystyle +\infty } , и «не число» (NaN). Для типа double они обозначаются Double.POSITIVE_INFINITY , Double.NEGATIVE_INFINITY , Double.NaN ; для типа float - так же, но с приставкой Float вместо Double. Минимальные и максимальные значения, принимаемые типами float и double, тоже стандартизованы.

Тип Длина (в байтах) Диапазон или набор значений
boolean 1 в массивах, 4 в переменных true, false
byte 1 −128..127
char 2 0..2 16 −1, или 0..65535
short 2 −2 15 ..2 15 −1, или −32768..32767
int 4 −2 31 ..2 31 −1, или −2147483648..2147483647
long 8 −2 63 ..2 63 −1, или примерно −9.2·10 18 ..9.2·10 18
float 4 -(2-2 −23)·2 127 ..(2-2 −23)·2 127 , или примерно −3.4·10 38 ..3.4·10 38 , а также − ∞ {\displaystyle -\infty } , ∞ {\displaystyle \infty } , NaN
double 8 -(2-2 −52)·2 1023 ..(2-2 −52)·2 1023 , или примерно −1.8·10 308 ..1.8·10 308 , а также − ∞ {\displaystyle -\infty } , ∞ {\displaystyle \infty } , NaN

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

Преобразования при математических операциях

В языке Java действуют следующие правила:

  1. Если один операнд имеет тип double, другой тоже преобразуется к типу double.
  2. Иначе, если один операнд имеет тип float, другой тоже преобразуется к типу float.
  3. Иначе, если один операнд имеет тип long, другой тоже преобразуется к типу long.
  4. Иначе оба операнда преобразуются к типу int.

Данный способ неявного преобразования встроенных типов полностью совпадает с преобразованием типов в C++ .

Объектные переменные, объекты, ссылки и указатели

В языке Java имеются только динамически создаваемые объекты. Причём переменные объектного типа и объекты в Java - совершенно разные сущности. Переменные объектного типа являются ссылками , то есть неявными указателями на динамически создаваемые объекты. Это подчёркивается синтаксисом описания переменных. Так, в Java нельзя писать:

double a [ 10 ][ 20 ]; Foo b (30 );

double a = new double [ 10 ][ 20 ]; Foo b = new Foo (30 );

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

Объектными являются переменные любого типа, кроме примитивного. Явных указателей в Java нет. В отличие от указателей C, C++ и других языков программирования, ссылки в Java в высокой степени безопасны благодаря жёстким ограничениям на их использование, в частности:

Благодаря таким специально введенным ограничениям в Java невозможно прямое манипулирование памятью на уровне физических адресов (хотя определено значение ссылки, не указывающей ни на что: null).

Если нужен указатель на примитивный тип, используются классы-обёртки примитивных типов: Boolean , Byte , Character , Short , Integer , Long , Float , Double .

Дублирование ссылок и клонирование

Из-за того, что объектные переменные являются ссылочными, при присваивании не происходит копирования объекта. Так, если написать

Foo foo , bar ; … bar = foo ;

то произойдет копирование адреса из переменной foo в переменную bar . То есть foo и bar будут указывать на одну и ту же область памяти, то есть на один и тот же объект; попытка изменить поля объекта, на который ссылается переменная foo , будет менять объект, с которым связана переменная bar , и наоборот. Если же необходимо получить именно ещё одну копию исходного объекта, пользуются или методом (функцией-членом, в терминологии C++) clone () , создающим копию объекта, или (реже) копирующим конструктором (конструкторы в Java не могут быть виртуальными, поэтому экземпляр класса-потомка будет неправильно скопирован конструктором класса-предка; метод клонирования вызывает нужный конструктор и тем самым позволяет обойти это ограничение).

Метод clone() требует, чтобы класс реализовывал интерфейс Cloneable (об интерфейсах см. ниже). Если класс реализует интерфейс Cloneable , по умолчанию clone() копирует все поля (мелкая копия ). Если требуется не копировать, а клонировать поля (а также их поля и так далее), надо переопределять метод clone() . Определение и использование метода clone() часто является нетривиальной задачей .

Инициализация переменных

Все переменные или требуют явного определения, или автоматически заполняются нулями (0, null, массивом нулей). Таким образом, исчезают гейзенбаги , связанные со случайным использованием неинициализированной памяти, характерные для низкоуровневых языков вроде C.

Сборка мусора

В языке Java невозможно явное удаление объекта из памяти - вместо этого реализована Сборка мусора . Традиционным [ ] приёмом, дающим сборщику мусора «намёк» на освобождение памяти, является присваивание переменной пустого значения null . Это, однако, не значит, что объект, заменённый значением null , будет непременно и немедленно удалён, но есть гарантия, что этот объект будет удалён именно в будущем. Данный приём всего лишь устраняет ссылку на объект, то есть отвязывает указатель от объекта в памяти. При этом следует учитывать, что объект не будет удален сборщиком мусора, пока на него указывает хотя бы одна ссылка из используемых переменных или объектов. Существуют также методы для инициации принудительной сборки мусора, но не гарантируется, что они будут вызваны исполняющей средой, и их не рекомендуется использовать для обычной работы.

Классы и функции

Java не является процедурным языком: любая функция может существовать только внутри класса. Это подчёркивает терминология языка Java, где нет понятий «функция» или «функция-член» (англ. member function ), а только метод . В методы превратились и стандартные функции. Например, в Java нет функции sin() , а есть метод Math.sin() класса Math (содержащего, кроме sin() , методы cos() , exp() , sqrt() , abs() и многие другие). Конструкторы в Java не считаются методами. Деструкторов в Java не существует, а метод finalize() ни в коем случае нельзя считать аналогом деструктора.

Конструкторы

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

Конструктор инициализирует объект непосредственно во время создания. Имя конструктора совпадает с именем класса, включая регистр, а по синтаксису конструктор похож на метод без возвращаемого значения.

private int Cat (); // так выглядит метод по имени Cat Cat (); // так выглядит конструктор класса Cat

В отличие от метода, конструктор никогда ничего не возвращает.

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

Создадим класс Box с конструктором, который просто установит начальные значения для коробки.

class Box { int width ; // ширина коробки int height ; // высота коробки int depth ; // глубина коробки // Конструктор Box (int a , int b ) { width = a ; height = b ; depth = 10 ; } // вычисляем объём коробки int getVolume () { return width * height * depth ; } }

Статические методы и поля

В Java (как и в C++) используются статические поля и статические методы (англ. static method - в теории программирования их также называют методами класса), которые задаются при помощи ключевого слова static . Статические поля (переменные класса) имеют тот же смысл, что и в C++: каждое такое поле является собственностью класса, поэтому для доступа к статическим полям не требуется создавать экземпляры соответствующего класса.

Например, математические функции, реализованные в классе Math , представляют собой как раз статические методы данного класса. Поэтому можно писать

double x = Math . sin (1 );

Math m = new Math (); double x = m . sin (1 );

Поскольку статические методы существуют независимо от объектов (экземпляров класса), они не имеют доступа к обычным (не статическим) полям и методам данного класса. В частности, при реализации статического метода недопустимо использовать идентификатор this .

Благодаря возможности статического импорта, возможно также вызывать статические функции и константы без указания класса, чтобы вместо кода

double x = Math . sin (Math . tan (Math . sqrt (y )) + Math . floor (24.5 )) + Math . cos (42 * Math . PI );

писать код

import static java.lang.Math.* ; ... double x = sin (tan (sqrt (y )) + floor (24.5 )) + cos (42 * PI );

Завершённость (final)

Ключевое слово final (финальный) имеет разные значения при описании поля, метода или класса.

  1. Финальное поле класса инициализируется при описании или в конструкторе класса (а статическое поле - в статическом блоке инициализации). Впоследствии его значение не может быть изменено. Если статическое поле класса или переменная проинициализированы константным выражением, они рассматриваются компилятором как именованная константа ; в таком случае их значение может быть использовано в операторах switch (для констант типа int), а также для условной компиляции (для констант типа boolean) при использовании с оператором if .
  2. Значения локальных переменных , а также параметров метода , помеченных ключевым словом final, не могут быть изменены после присвоения. При этом их значения могут использоваться внутри анонимных классов .
  3. Метод класса, отмеченный словом final, не может быть переопределён при наследовании.
  4. Финальный класс не может иметь наследников.

Абстрактность

В Java методы, не объявленные явно как static , final или private , являются виртуальными в терминологии C++: при вызове метода, по-разному определённого в базовом и наследующем классах, всегда производится проверка времени выполнения.

Абстрактным методом (модификатор abstract) в Java называется метод, для которого заданы параметры и тип возвращаемого значения, но не задано тело. Абстрактный метод определяется в классах-наследниках. Аналог абстрактного метода в C++ - чисто виртуальная функция (pure virtual function). Для того чтобы в классе можно было описывать абстрактные методы, сам класс тоже должен быть описан как абстрактный. Объекты абстрактного класса создавать нельзя.

Интерфейсы

Высшей степенью абстрактности в Java является интерфейс (модификатор interface). Все методы интерфейса абстрактны: описатель abstract даже не требуется. Интерфейс в Java не считается классом, хотя, по сути, является полностью абстрактным классом. Класс может наследовать/расширять (extends) другой класс или реализовывать (implements) интерфейс. Кроме того, интерфейс может наследовать/расширять другой интерфейс.

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

Интерфейсы можно использовать в качестве типов параметров методов. Нельзя создавать экземпляры интерфейсов.

Маркерные интерфейсы

В Java есть интерфейсы, которые не содержат методов для реализации, а специальным образом обрабатываются JVM:

  • java.lang.Cloneable
  • java.io.Serializable
  • java.util.RandomAccess
  • java.rmi.Remote

Шаблоны в Java (generics)

Начиная с версии Java 5 в языке появился механизм обобщённого программирования - шаблоны, внешне близкие к шаблонам C++. С помощью специального синтаксиса в описании классов и методов можно указать параметры-типы, которые внутри описания могут использоваться в качестве типов полей, параметров и возвращаемых значений методов.

// Объявление обобщённого класса class GenericClass < E > { E getFirst () { ... } void add (E obj ) { ... } } // Использование обобщённого класса в коде GenericClass < String > var = new GenericClass < String >(); var . add ("qwerty" ); String p = var . getFirst ();

Допускается обобщённое объявление классов, интерфейсов и методов. Кроме того, синтаксис поддерживает ограниченные объявления типов-параметров: указание в объявлении конструкции вида требует, чтобы тип-параметр T реализовывал интерфейсы A, B, C и так далее, а конструкция требует, чтобы тип-параметр T был типом C или одним из его предков.

В отличие от шаблонов C#, шаблоны Java не поддерживаются средой исполнения - компилятор просто создаёт байт-код, в котором никаких шаблонов уже нет. Реализация шаблонов в Java принципиально отличается от реализации аналогичных механизмов в C++: компилятор не порождает для каждого случая использования шаблона отдельный вариант класса или метода-шаблона, а просто создаёт одну реализацию байт-кода, содержащую необходимые проверки и преобразования типов. Это приводит к ряду ограничений использования шаблонов в программах на Java.

Проверка принадлежности к классу

В Java можно явно проверить, к какому классу принадлежит объект. Выражение foo instanceof Foo истинно, если объект foo принадлежит классу Foo или его наследнику, или реализует интерфейс Foo (или, в общем виде, наследует класс, который реализует интерфейс, который наследует Foo).

Далее функция getClass() , определённая для всех объектов, выдаёт объект типа Class . Для каждого класса создаётся не более одного описывающего его объекта типа Class , поэтому эти объекты можно сравнивать. Так, например, foo.getClass() == bar.getClass() будет истинно, если объекты foo и bar принадлежат к одному классу.

Кроме того, объект типа Class любого типа можно получить так: Integer.class , Object.class .

Прямое сравнение классов не всегда является оптимальным средством проверки на принадлежность к классу. Зачастую вместо него используют функцию isAssignableFrom() . Эта функция определена у объекта типа Class и принимает объект типа Class в качестве параметра. Таким образом, вызов Foo.class.isAssignableFrom(Bar.class) вернёт true в случае, если Foo является предком класса Bar . Так как все объекты являются потомками типа Object , вызов Object.class.isAssignableFrom() всегда вернёт true .

В паре с упомянутыми функциями объекта типа Class используются также функции isInstance() (эквивалентно instanceof), а также cast() (преобразует параметр в объект выбранного класса).

Средства разработки ПО

  • JDK - помимо набора библиотек для платформ Java SE и Java EE , содержит компилятор командной строки javac и набор утилит, также работающих в режиме командной строки.
  • NetBeans IDE - свободная интегрированная среда разработки для всех платформ Java - Java ME , Java SE и Java EE . Пропагандируется Oracle , владельцем технологии Java, как базовое средство для разработки ПО на языке Java и других языках ( , C++ , PHP , Fortran и др.).
  • Eclipse IDE - свободная интегрированная среда разработки для

Последнее обновление: 26.09.2018

На сегодняшний момент язык Java является одним из самых распространенных и популярных языков программирования. Первая версия языка появилась еще в 1996 году в недрах компании Sun Microsystems, впоследствии поглощенной компанией Oracle. Java задумывался как универсальный язык программирования, который можно применять для различного рода задач. И к настоящему времени язык Java проделал большой путь, было издано множество различных версий. Текущей версией является Java 11, которая вышла в сентябре 2018 года. А Java превратилась из просто универсального языка в целую платформу и экосистему, которая объединяет различные технологии, используемые в целого ряда задач: от создания десктопных приложений до написания крупных веб-порталов и сервисов. Кроме того, язык Java активно применяется для создания программного обеспечения для целого ряда устройств: обычных ПК, планшетов, смартфонов и мобильных телефонов и даже бытовой техники. Достаточно вспомнить популярность мобильной ОС Android, большинство программ для которой пишутся именно на Java.

Особенности Java

Ключевой особенностью языка Java является то, что его код сначала транслируется в специальный байт-код, независимый от платформы. А затем этот байт-код выполняется виртуальной машиной JVM (Java Virtual Machine). В этом плане Java отличается от стандартных интерпретируемых языков как PHP или Perl, код которых сразу же выполняется интерпретатором. В то же время Java не является и чисто компилируемым языком, как С или С++.

Подобная архитектура обеспечивает кроссплатформенность и аппаратную переносимость программ на Java, благодаря чему подобные программы без перекомпиляции могут выполняться на различных платформах - Windows, Linux, Mac OS и т.д. Для каждой из платформ может быть своя реализация виртуальной машины JVM, но каждая из них может выполнять один и тот же код.

Java является языком с Си-подобным синтаксисом и близок в этом отношении к C/C++ и C#. Поэтому, если вы знакомы с одним из этих языков, то овладеть Java будет легче.

Еще одной ключевой особенностью Java является то, что она поддерживает автоматическую сборку мусора. А это значит, что вам не надо освобождать вручную память от ранее использовавшихся объектов, как в С++, так как сборщик мусора это сделает автоматически за вас.

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

Установка Java

Для работы программ на языке Java на целевой машине должна быть установлена JRE (Java Runtime Environment). JRE представляет минимальную реализацию виртуальной машины, а также библиотеку классов. Поэтому, если мы хотим запускать программы, то нам надо установить JRE. Для каждой конкретной платформы имеется своя версия JRE.

Однако, так как мы собираемся не только запускать программы, но и разрабатывать их, нам потребуется специальный комплект для разработки JDK (Java Development Kit). JDK уже содержит JRE, а также включает ряд дополнительных программ и утилит, в частности компилятор Java.

Загрузить и установить соответствующую версию JDK можно с с официального сайта Oracle: http://www.oracle.com/technetwork/java/javase/downloads/index.html

Итак, с выше упомянутого адреса загрузим программу установки JDK для последней версии Java.

Затем нас перебросит на страницу, где надо выбрать версию для целевой ОС - Windows, MacOS или Linux:

Для каждой ОС есть два варианта загрузки: в виде установщика, либо в виде архива, который не надо устанавливать. Например, моя ОС - Windows, поэтому я загружаю файл jdk_11_windows-x64_bin.exe, который представляет программу установки.

После загрузки запустим программу установки:

Оставим все опции по умолчанию и нажмем на Next для выполнения установки.

После завершения установки JDK мы увидим вот такое окно:

Итак, после установки JDK создадим первую программу на Java.