Помню, как впервые открыл IDE и начал писать свою первую программу на Java. Создал переменную, написал int x = 5, запустил... и понятия не имел, что только что произошло. Почему именно int? Что за x? И главное — зачем это всё нужно? Если ты сейчас в похожей ситуации — не переживай, мы всё разберём. Сегодня поговорим о примитивных типах данных в Java. Звучит скучно? Ну, это как учить алфавит перед тем, как писать книги. Да, не самое захватывающее занятие, но без этого никуда.

Что вообще такое примитивные типы?

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

Целочисленные типы: когда нужны целые числа

Табл. Характеристики целочисленных типов Java
Примитивные типы Java - 2Начнём с самых популярных — типов для хранения целых чисел. Их аж пять штук! Сначала я тоже не понимал, зачем столько. Ну есть число 5, и всё, какая разница? А разница вот в чём: каждый тип "съедает" разное количество памяти и может хранить числа в определённом диапазоне.

byte — самый маленький

Размер: 1 байт (8 бит) Диапазон: от -128 до 127 Честно? Я byte в реальной работе использую крайне редко. Разве что когда работаешь с картинками или сетевыми пакетами, где каждый байт на счету. Для обычных программ он слишком мелкий.
byte temperature = 25;
byte frozenWater = -10;

// А вот так уже не получится — число слишком большое!
// byte bigNumber = 200; // Ошибка компиляции!

short — чуть побольше

Размер: 2 байта (16 бит) Диапазон: от -32,768 до 32,767 Тоже редкий гость в коде. Может пригодиться, если у тебя миллион чисел и нужно экономить память. Но обычно проще использовать...

int — твой лучший друг

Размер: 4 байта (32 бита) Диапазон: от -2,147,483,648 до 2,147,483,647 Вот это да! int — это рабочая лошадка Java. Процентов 90 всех целочисленных переменных в коде — именно int. Диапазон огромный, работает быстро, памяти много не жрёт.
int age = 25;
int yearlyIncome = 50000;
int populationOfCity = 1500000;

// Можно записывать большие числа с подчёркиваниями для читаемости
int million = 1_000_000; // Так гораздо понятнее!

System.out.println("Миллион: " + million); // Выведет: Миллион: 1000000
Кстати, видишь эти подчёркивания в числе? Это фича появилась в Java 7, и она офигенно удобная. Компилятор их просто игнорирует, но для человека читать становится в разы легче.

long — для по-настоящему больших чисел

Размер: 8 байт (64 бита) Диапазон: от -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807 Когда int уже не хватает (например, работаешь с миллисекундами с начала эпохи Unix или считаешь национальный долг), приходит на помощь long.
long worldPopulation = 7_800_000_000L; // Обрати внимание на L в конце!
long millisecondsSince1970 = System.currentTimeMillis();

System.out.println("Миллисекунд с 1970 года: " + millisecondsSince1970);
// Выведет что-то типа: Миллисекунд с 1970 года: 1734527654321
Важно! Видишь букву L в конце числа? Без неё Java подумает, что это int, и если число слишком большое — получишь ошибку. Можно писать и маленькую l, но она похожа на единицу, так что лучше использовать большую L.

char — особенный тип для символов

Размер: 2 байта (16 бит) Диапазон: от 0 до 65,535 (без знака!) Технически char тоже целочисленный, но используется для хранения символов. Java работает с Unicode, поэтому один char может хранить любой символ — латиницу, кириллицу, иероглифы, эмодзи (ну, почти).
char letter = 'A';
char cyrillic = 'Я';
char digit = '5'; // Это символ, не число!

// Можно записывать через Unicode-код
char smiley = '\u263A'; // ☺

System.out.println(letter); // A
System.out.println(smiley); // ☺

// А ещё char — это число!
char a = 'A';
System.out.println((int) a); // 65 — это код символа 'A' в Unicode
Важный момент: символы пишутся в одинарных кавычках 'A', а строки — в двойных "Hello". Это разные вещи!

Escape-последовательности: как записать "невидимые" символы

Табл. Escape-последовательности, используемые в языке Java
Примитивные типы Java - 3А теперь прикольная штука. Как записать символ, которого нет на клавиатуре? Например, перенос строки или табуляцию? Для этого в Java есть специальные комбинации с обратным слэшем \ — они называются escape-последовательности. Вот самые важные, которые будешь использовать постоянно: \n — перенос строки (new line). Это твой лучший друг при выводе текста:
System.out.println("Привет\nМир!");
// Выведет:
// Привет
// Мир!
\t — табуляция (tab). Удобно для форматирования текста:
System.out.println("Имя:\tИван\nВозраст:\t25");
// Выведет:
// Имя:    Иван
// Возраст:    25
\" — двойная кавычка. Нужна, когда хочешь вставить кавычки в строку:
System.out.println("Он сказал: \"Java — это круто!\"");
// Выведет: Он сказал: "Java — это круто!"
\' — одинарная кавычка (для char):
char quote = '\'';
System.out.println(quote); // '
\\ — сам обратный слэш. Да, чтобы вывести один слэш, нужно написать два:
System.out.println("Путь к файлу: C:\\Users\\Student\\file.txt");
// Выведет: Путь к файлу: C:\Users\Student\file.txt
Есть ещё \r (возврат каретки), \b (backspace) и \f (прогон страницы), но честно — я их за 10 лет ни разу не использовал. Запоминай то, что действительно нужно: \n, \t, \" и \\.

Системы счисления: шестнадцатеричные числа

Иногда в коде увидишь странные числа типа 0xFF или 0x1A2B. Это шестнадцатеричная система счисления. Программисты её любят, потому что она удобно связана с байтами.
int hex = 0xFF; // Это 255 в десятичной системе
int anotherHex = 0x1A; // Это 26

System.out.println(hex); // 255
System.out.println(anotherHex); // 26
Совет новичку: не паникуй, когда видишь такие числа. На первых порах просто знай, что 0x в начале означает шестнадцатеричное число. Позже разберёшься подробнее. А вот восьмеричные числа (которые начинаются с нуля, типа 077) лучше вообще забудь. Они в современном коде почти не используются, а вот проблем могут создать кучу. Случайно напишешь int x = 010, думая, что это десять, а на самом деле получишь восемь. Неприятно, правда?

Вещественные типы: когда нужны дроби

Табл. Характеристики вещественных типов Java
Примитивные типы Java - 4Хорошо, с целыми числами разобрались. А если нужно работать с дробями? Скажем, посчитать среднюю температуру или цену со скидкой?

float — число с плавающей точкой обычной точности

Размер: 4 байта (32 бита) Точность: ~6-7 значащих цифр Честно говоря, float в реальной работе я использую крайне редко. Он не очень точный и требует добавления буквы f в конце числа, что бесит.
float price = 19.99f; // Не забывай про f!
float temperature = -3.5f;

System.out.println(price); // 19.99

double — для точных вычислений

Размер: 8 байт (64 бита) Точность: ~15-16 значащих цифр Вот это уже серьёзно! double — стандартный выбор для работы с дробными числами в Java. Точнее, быстрее, удобнее.
double pi = 3.14159265359;
double bankBalance = 1500.75;

// Можно использовать научную нотацию
double speed = 3.0e8; // Это 3.0 × 10^8 (скорость света в м/с)

System.out.println("Пи примерно равно: " + pi); // Пи примерно равно: 3.14159265359
System.out.println("Скорость света: " + speed); // Скорость света: 3.0E8

Особенности работы с числами с плавающей точкой

Тут есть один коварный момент, о котором нужно знать сразу. Компьютеры не могут хранить дробные числа абсолютно точно. Посмотри на этот пример:
double a = 0.1;
double b = 0.2;
double sum = a + b;

System.out.println(sum); // Ожидаешь 0.3? А получишь 0.30000000000000004
Да-да, такое бывает! Это не баг Java, а особенность представления дробных чисел в памяти компьютера. Для большинства задач эта погрешность незаметна, но если работаешь с деньгами — никогда не используй double! Для финансовых расчётов есть специальный класс BigDecimal (с ним познакомишься позже на курсе JavaRush). А ещё у float и double есть специальные значения:
double positive = 5.0 / 0.0; // Положительная бесконечность
double negative = -5.0 / 0.0; // Отрицательная бесконечность
double notANumber = 0.0 / 0.0; // "Не число" (NaN - Not a Number)

System.out.println(positive); // Infinity
System.out.println(negative); // -Infinity
System.out.println(notANumber); // NaN

// Проверить на NaN можно так:
if (Double.isNaN(notANumber)) {
    System.out.println("Это не число!");
}
Когда впервые увидел, что деление на ноль не вызывает ошибку, а даёт бесконечность, был в шоке. Но это на самом деле удобно — программа не падает, и ты можешь проверить результат.

boolean — истина или ложь

И наконец, самый простой тип. boolean может хранить только два значения: true (истина) или false (ложь). Всё. Размер: зависит от JVM (обычно 1 бит, но может быть и 1 байт)
boolean isJavaFun = true;
boolean isEasy = false;
boolean iAmLearning = true;

// Чаще всего используется в условиях
if (isJavaFun) {
    System.out.println("Java это весело!"); // Это выполнится
}

if (isEasy) {
    System.out.println("Java легко даётся"); // А это нет
}
В отличие от C, где 0 означало ложь, а любое другое число — истину, в Java для логических значений есть отдельный тип. Это круто, потому что избавляет от кучи ошибок. Попробуешь написать if (1) — компилятор сразу ругнётся.

Практические советы для начинающих

После всей этой теории дам несколько советов из личного опыта: 1. Начни с int и double На первых порах используй только int для целых чисел и double для дробных. Остальные типы освоишь по мере необходимости. Серьёзно, не усложняй. 2. Не экономь память без причины Видел код, где новички пытаются везде использовать byte вместо int "для экономии памяти". Друзья, в 2024 году это не имеет смысла. Используй byte только когда действительно нужно (работа с сетью, файлами, изображениями). 3. Помни про L и f Для long — добавляй L в конце, для floatf. Без них получишь ошибки или неожиданное поведение. 4. Не сравнивай double через == Из-за погрешности вычислений два double могут быть почти равны, но не точно равны. Лучше проверяй, что разница между ними меньше какого-то маленького числа (epsilon).
double a = 0.1 + 0.2;
double b = 0.3;

// Плохо:
if (a == b) { // Может не сработать!
    System.out.println("Равны");
}

// Хорошо:
double epsilon = 0.0001;
if (Math.abs(a - b) < epsilon) {
    System.out.println("Практически равны"); // Это сработает
}

Итог

Поздравляю! Ты только что освоил фундамент Java. Примитивные типы — это как буквы алфавита. Сами по себе они простые, но из них строится всё остальное. Дальше тебя ждут операторы (сложение, вычитание, сравнение), условия (if-else), циклы... и куча интересного! Так что вперёд! Следующий шаг — узнать, что со всеми этими типами можно делать. А там уже недалеко и до первой настоящей программы.