🎓 УРОК 2: Переменные. Примитивные типы данных
📌 ЦЕЛИ УРОКА
К концу этого урока ты сможешь:
- Объяснить, что такое переменная в Java и как работает статическая типизация
- Перечислить все 8 примитивных типов данных Java и знать диапазоны их значений
- Правильно объявлять, инициализировать и использовать переменные разных типов
- Понимать разницу между объявлением и инициализацией переменной
- Объяснить, что происходит в памяти при создании примитивной переменной
- Применять правила именования переменных и понимать конвенции camelCase
🔗 СВЯЗЬ С ПРЕДЫДУЩИМИ ТЕМАМИ
В Уроке 1 мы уже мельком использовали числа в примерах (5 + 3, 10 > 5), но не объявляли их как переменные — писали "жёстко" внутри println. Сегодня разберём, как хранить данные в именованных ячейках памяти — переменных.
Также вспомним: Java — статически типизированный язык. Мы уже видели в структуре main, что параметр объявлен как String[] args — то есть тип указывается явно. Сегодня разберём эту концепцию досконально, потому что она пронизывает весь язык.
📖 ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
1. Что такое переменная и статическая типизация
Переменная — это именованная область памяти, которая хранит значение определённого типа.
Ключевое слово здесь — "определённого типа". В Java тип переменной фиксируется в момент объявления и не может измениться в течение жизни переменной. Это называется статическая типизация (static typing).
int age = 25; // переменная age навсегда останется типом int
age = "двадцать пять"; // ❌ ОШИБКА КОМПИЛЯЦИИ! Нельзя присвоить строку переменной типа int
Почему так строго? Компилятор Java проверяет типы ещё ДО запуска программы (на этапе компиляции). Это позволяет отловить огромное количество ошибок заранее, а не во время выполнения программы у пользователя. Это философия надёжности Java: лучше упасть с понятной ошибкой компиляции, чем сломаться в проде через полгода из-за неожиданного типа данных.
Компилятор всегда должен знать заранее, сколько памяти выделить и какие операции допустимы для переменной — а это возможно только если тип известен и неизменен.
2. Синтаксис объявления переменной
Общая форма:
тип имяПеременной = значение;
Например:
int count = 10;
double price = 99.99;
boolean isActive = true;
Три обязательных части:
- Тип — что за данные будут храниться (
int,double,booleanи т.д.) - Имя — идентификатор переменной, по которому мы к ней обращаемся
- Значение — то, что записывается в переменную (может отсутствовать при объявлении без инициализации)
3. Объявление vs инициализация — важное разграничение
Это два разных, хоть и часто совмещаемых действия:
Объявление (declaration) — сообщаем компилятору, что переменная с таким именем и типом существует:
int age; // объявили переменную age типа int, но значения ещё нет
Инициализация (initialization) — присваиваем переменной первое значение:
age = 25; // инициализировали ранее объявленную переменную
Их можно объединить в одну строку (и обычно так и делают):
int age = 25; // объявление + инициализация одновременно
⚠️ Критически важный момент: в Java локальные переменные (объявленные внутри метода) не имеют значения по умолчанию. Если ты объявишь переменную, но попытаешься её использовать до присвоения значения — компилятор выдаст ошибку:
public static void main(String[] args) {
int x; // объявили, но не инициализировали
System.out.println(x); // ❌ ОШИБКА: variable x might not have been initialized
}
Это защита от неопределённого поведения — компилятор не даст тебе случайно использовать "мусорное" значение.
(Забегая вперёд: поля класса (не локальные переменные) ведут себя иначе — они получают значения по умолчанию автоматически. Но об этом подробно — в уроке про классы, урок 14.)
4. Восемь примитивных типов данных
Java — язык с чёткой иерархией типов. Есть 8 примитивных типов (primitive types) — они хранят "сырые" значения напрямую, а не ссылки на объекты (про ссылочные типы — в Уроке 3).
Разделим их на 4 категории:
🔢 Целочисленные типы (integer types)
| Тип | Размер | Диапазон значений | Пример |
|---|---|---|---|
byte |
8 бит (1 байт) | от -128 до 127 | byte b = 100; |
short |
16 бит (2 байта) | от -32,768 до 32,767 | short s = 30000; |
int |
32 бита (4 байта) | от -2,147,483,648 до 2,147,483,647 (≈ ±2.1 млрд) | int i = 100000; |
long |
64 бита (8 байт) | от -9.2×10¹⁸ до 9.2×10¹⁸ | long l = 10000000000L; |
По умолчанию любое целое число в коде — это int. Если нужно long, обязательно добавляй суффикс L (заглавная или строчная, но заглавную предпочитают — легче отличить от единицы):
long bigNumber = 3000000000L; // без L будет ошибка компиляции —
// число не помещается в int
Почему четыре разных типа для целых чисел? Это про экономию памяти. Если ты храмишь возраст человека (максимум ~150), незачем выделять 4 байта под int, если хватит 1 байта byte. На современных компьютерах разница в памяти для одной переменной несущественна, но при работе с массивами из миллионов элементов выбор правильного типа критически важен для производительности.
🔢 Типы с плавающей точкой (floating-point types)
| Тип | Размер | Точность | Пример |
|---|---|---|---|
float |
32 бита | ~6-7 значащих цифр | float f = 3.14f; |
double |
64 бита | ~15-16 значащих цифр | double d = 3.14159265; |
По умолчанию любое дробное число в коде — это double. Если нужен float, обязателен суффикс f:
float price = 19.99f; // без f — ошибка компиляции
double price2 = 19.99; // а тут суффикс не нужен, double по умолчанию
⚠️ Важнейший подводный камень: типы с плавающей точкой хранят числа неточно из-за особенностей двоичного представления дробей. Классический пример:
System.out.println(0.1 + 0.2); // выведет 0.30000000000000004, а не 0.3!
Это не баг Java, а фундаментальная особенность стандарта IEEE 754, по которому работают float/double во всех языках программирования. Для точных денежных расчётов используют специальный класс BigDecimal (разберём в продвинутых темах), а не double.
Когда использовать double, а когда float? В подавляющем большинстве случаев — double. float используют редко, в основном там, где критична экономия памяти (например, в графике, машинном обучении с большими массивами данных).
🔤 Символьный тип
| Тип | Размер | Диапазон | Пример |
|---|---|---|---|
char |
16 бит | от 0 до 65,535 (символы Unicode) | char letter = 'A'; |
char хранит один символ в одинарных кавычках (не путать со строками в двойных кавычках — про это подробно в Уроке 3):
char grade = 'A';
char digit = '5'; // это символ '5', а не число 5!
char unicodeSymbol = '\u0041'; // тоже 'A', через Unicode-код
Интересный факт: char в Java — это фактически 16-битное число (беззнаковое), поэтому с ним можно выполнять арифметику:
char letter = 'A';
System.out.println((int) letter); // выведет 65 (код символа 'A' в Unicode/ASCII)
✅ Логический тип
| Тип | Размер | Значения | Пример |
|---|---|---|---|
boolean |
не определён формально (JVM-зависимо, условно 1 бит) | true / false |
boolean isJavaFun = true; |
Только два возможных значения — true или false. Никаких 0 и 1 вместо них, как в некоторых языках!
boolean isReady = true;
boolean hasErrors = 0; // ❌ ОШИБКА! boolean не совместим с int в Java
5. Таблица-памятка всех примитивов
┌───────────┬──────────┬─────────────────────────────────────┐
│ Тип │ Размер │ Что хранит │
├───────────┼──────────┼─────────────────────────────────────┤
│ byte │ 1 байт │ Целые числа (-128...127) │
│ short │ 2 байта │ Целые числа (-32768...32767) │
│ int │ 4 байта │ Целые числа (±2.1 млрд) — по умолч. │
│ long │ 8 байт │ Большие целые числа (нужен суфф. L) │
│ float │ 4 байта │ Дробные числа (нужен суфф. f) │
│ double │ 8 байт │ Дробные числа — по умолчанию │
│ char │ 2 байта │ Один символ (в одинарных кавычках) │
│ boolean │ — │ true / false │
└───────────┴──────────┴─────────────────────────────────────┘
6. Что происходит в памяти при создании примитивной переменной
Когда JVM выполняет метод main, для него выделяется область в стеке (Stack). Локальные примитивные переменные хранятся непосредственно в стеке, со своим значением напрямую (не через ссылку, в отличие от объектов, которые лежат в куче — про это подробно в Уроке 3).
public static void main(String[] args) {
int age = 25; // в стеке создаётся ячейка "age" со значением 25
double price = 9.99; // в стеке создаётся ячейка "price" со значением 9.99
}
Схематично:
СТЕК (Stack)
┌─────────────────┐
│ main() frame │
│ ┌─────────────┐ │
│ │ age = 25 │ │
│ │ price = 9.99 │ │
│ └─────────────┘ │
└─────────────────┘
Когда метод main завершается, весь его "фрейм" в стеке уничтожается автоматически — переменные age и price перестают существовать. Это очень быстрый и эффективный механизм работы с памятью для простых значений.
7. Правила именования переменных (identifiers)
Технические правила (обязательные, иначе ошибка компиляции):
- Может содержать буквы, цифры,
_и$ - Не может начинаться с цифры
- Не может быть зарезервированным словом (
int,class,publicи т.д.) - Регистрозависимость:
ageиAge— разные переменные
Соглашения (best practice, не обязательны технически, но крайне важны для читаемости кода):
- Используется camelCase: первое слово с маленькой буквы, каждое следующее — с большой
int studentAge = 20; // ✅ правильно
int student_age = 20; // ⚠️ работает, но не Java-стиль (это стиль Python/C)
int StudentAge = 20; // ⚠️ работает, но заглавная первая буква — конвенция для классов, не переменных
- Имена должны быть осмысленными:
int a = 25; // ❌ плохо — непонятно, что это
int userAge = 25; // ✅ хорошо — сразу понятно назначение
8. Константы: ключевое слово final
Если значение переменной никогда не должно меняться после инициализации, используют модификатор final:
final double PI = 3.14159;
PI = 3.15; // ❌ ОШИБКА компиляции: cannot assign a value to final variable PI
По конвенции константы называют ЗАГЛАВНЫМИ_БУКВАМИ с подчёркиванием:
final int MAX_USERS = 100;
final String APP_NAME = "MyApp"; // забегая вперёд, String разберём в Уроке 3
(Подробно про final — отдельный Урок 22, сегодня только знакомство с концепцией.)
9. Множественное объявление переменных одного типа
Java позволяет объявить несколько переменных одного типа в одной строке:
int x = 1, y = 2, z = 3;
Технически работает, но на практике избегай такого стиля — читаемость кода важнее компактности. Предпочитай:
int x = 1;
int y = 2;
int z = 3;
💻 ПРИМЕРЫ КОДА
Пример 1: Базовое объявление разных типов
public class Main {
public static void main(String[] args) {
int age = 25; // целое число
double salary = 55000.50; // дробное число
char grade = 'A'; // символ
boolean isEmployed = true; // логическое значение
System.out.println("Возраст: " + age);
System.out.println("Зарплата: " + salary);
System.out.println("Оценка: " + grade);
System.out.println("Трудоустроен: " + isEmployed);
}
}
Вывод в консоли:
Возраст: 25
Зарплата: 55000.5
Оценка: A
Трудоустроен: true
Разбор построчно:
- Строка 3: создаётся переменная
ageтипаintв стеке методаmain, туда записывается значение25 - Строка 4: аналогично,
double salary— 8 байт в стеке под дробное число - Строка 5:
char gradeв одинарных кавычках — важно не перепутать с двойными - Строка 6:
boolean isEmployed— толькоtrue/false - Строки 8-11: конкатенация строк (текст в кавычках) с переменными через
+— компилятор автоматически преобразует значения в строковое представление для вывода
Пример 2: Диапазоны типов и переполнение (overflow)
public class Main {
public static void main(String[] args) {
byte maxByte = 127;
System.out.println("Максимум byte: " + maxByte);
maxByte = (byte) (maxByte + 1); // выходим за границу диапазона!
System.out.println("После переполнения: " + maxByte);
}
}
Вывод в консоли:
Максимум byte: 127
После переполнения: -128
Что произошло: byte вмещает значения от -128 до 127. Когда мы прибавляем 1 к максимальному значению 127, происходит переполнение (overflow) — значение "перескакивает" на противоположный край диапазона, на -128. Это классическая проблема всех языков с фиксированной битностью типов, не только Java. Важно об этом знать, чтобы не получить неожиданный баг в реальном проекте.
(Про приведение типов (byte) подробно поговорим в Уроке 30, сегодня просто демонстрация проблемы.)
Пример 3: Ошибка неинициализированной переменной
public class Main {
public static void main(String[] args) {
int result; // объявили, не инициализировали
System.out.println(result); // ❌ ОШИБКА компиляции
}
}
Сообщение компилятора:
error: variable result might not have been initialized
System.out.println(result);
^
1 error
Как исправить:
int result = 0; // всегда инициализируй переменную перед использованием
System.out.println(result); // теперь работает
Пример 4: Разница float и double + необходимость суффиксов
public class Main {
public static void main(String[] args) {
float price = 19.99f; // суффикс f обязателен!
double weight = 72.5; // суффикс не нужен, double — тип по умолчанию
System.out.println("Цена: " + price);
System.out.println("Вес: " + weight);
// long bigNum = 5000000000; // ❌ закомментировано намеренно —
// без суффикса L будет ошибка компиляции,
// т.к. число превышает диапазон int
long bigNum = 5000000000L; // ✅ с суффиксом L — работает
System.out.println("Большое число: " + bigNum);
}
}
Вывод в консоли:
Цена: 19.99
Вес: 72.5
Большое число: 5000000000
⚠️ Если убрать f у float:
float price = 19.99; // ❌ ошибка: incompatible types: possible lossy conversion from double to float
Компилятор скажет, что по умолчанию 19.99 — это double, а double нельзя автоматически "втиснуть" в float без явного приведения (double занимает больше памяти и точнее, чем float) — это защита от потери точности.
Пример 5: Демонстрация неточности double (классическая ловушка)
public class Main {
public static void main(String[] args) {
double a = 0.1;
double b = 0.2;
double sum = a + b;
System.out.println("0.1 + 0.2 = " + sum);
System.out.println("Равно ли 0.3? " + (sum == 0.3));
}
}
Вывод в консоли:
0.1 + 0.2 = 0.30000000000000004
Равно ли 0.3? false
Почему так происходит: дробные числа в двоичной системе не всегда представимы точно (аналогично тому, как 1/3 нельзя точно записать конечной десятичной дробью). Это стандартная особенность IEEE 754, по которому работают float/double во всех современных языках. Для сравнения дробных чисел на "почти равенство" используют небольшую погрешность (эпсилон), а для денежных расчётов — специальный класс BigDecimal.
⌨️ ГОРЯЧИЕ КЛАВИШИ INTELLIJ IDEA
| Действие | Windows/Linux | macOS | Когда использовать |
|---|---|---|---|
| Переименовать переменную везде в коде | Shift + F6 |
Shift + F6 |
Изменить имя переменной сразу во всех местах использования — безопаснее, чем ручная замена |
| Быстрое исправление (Quick Fix) | Alt + Enter |
Option + Enter |
Когда IDE подчёркивает ошибку/предупреждение — покажет варианты исправления (например, добавить суффикс L) |
| Извлечь переменную (Extract Variable) | Ctrl + Alt + V |
Cmd + Alt + V |
Выделить кусок выражения и превратить его в отдельную переменную автоматически |
| Показать тип переменной / информацию о выражении | Ctrl + Shift + P |
Cmd + Shift + P |
Узнать выведенный тип выражения, не считая вручную |
| Дублировать строку | Ctrl + D |
Cmd + D |
Быстро скопировать строку объявления переменной для создания похожей |
| Перейти к объявлению переменной | Ctrl + B (или Ctrl+клик) |
Cmd + B |
Найти, где переменная была объявлена, в большом файле |
💡 Особенно полезно сегодня: Alt+Enter — когда напишешь float price = 19.99; без суффикса, IDE подчеркнёт ошибку, и через Alt+Enter можно выбрать автоматическое исправление "Add 'f' suffix".
🎯 ПРАКТИЧЕСКИЕ ЗАДАНИЯ
Задание 1 (5 мин) — Все типы разом
Объяви по одной переменной каждого из 8 примитивных типов, инициализируй их произвольными подходящими значениями и выведи все в консоль с подписями.
Критерий проверки: используются все 8 типов (byte, short, int, long, float, double, char, boolean), нет ошибок компиляции.
Задание 2 (10 мин) — Профиль пользователя
Создай набор переменных, описывающих профиль пользователя: имя (пока просто отдельные буквы через char, или пропусти — String будет в след. уроке), возраст (int), рост в метрах (double), является ли студентом (boolean), первая буква имени (char). Выведи всё в читаемом формате.
Пример вывода:
Возраст: 22
Рост: 1.78
Студент: true
Первая буква имени: А
Задание 3 (10 мин) — Найди и исправь ошибку
Дан код с 3 ошибками. Найди их все, объясни причину и исправь:
public class Main {
public static void main(String[] args) {
int count;
System.out.println(count);
float weight = 65.5;
long population = 8000000000;
}
}
Критерий проверки: все 3 ошибки найдены (использование неинициализированной переменной, отсутствие суффикса f, отсутствие суффикса L), код компилируется после исправления.
Задание 4 (10 мин) — Демонстрация переполнения
Напиши код, который демонстрирует переполнение для типа short (диапазон -32768...32767). Выведи значение до и после переполнения, объясни результат комментарием в коде.
Задание 5 (15 мин) — Работа с константами
Создай программу-калькулятор площади круга, используя константу PI (объявленную через final), и переменную радиуса. Выведи результат.
Пример:
final double PI = 3.14159;
double radius = 5.0;
double area = PI * radius * radius;
System.out.println("Площадь круга: " + area);
Попробуй затем изменить значение PI после объявления и убедись, что компилятор выдаёт ошибку — приложи текст этой ошибки.
Задание 6 (15 мин) — Ловушка double
Воспроизведи пример с 0.1 + 0.2 из теории. Затем попробуй сложить 0.1f + 0.2f (используя float вместо double) — сравни результаты. Объясни своими словами (в комментарии в коде), почему это происходит.
Задание 7 (15 мин) — char как число
Напиши код, который:
- Объявляет
char letter = 'Z'; - Выводит саму букву
- Выводит её числовой Unicode-код (используя приведение
(int) letter) - Прибавляет к букве число 1 и выводит результат — что получилось? (Подсказка: результат сам по себе будет числом типа
int, если явно не привести обратно кchar)
Критерий проверки: понимание того, что char внутри — это число, и можно к нему применять арифметику.
❓ ПРОВЕРОЧНЫЕ ВОПРОСЫ
1. Что такое статическая типизация?
Ответ
Тип переменной определяется на этапе компиляции и фиксируется — его нельзя изменить в течение "жизни" переменной. Компилятор проверяет корректность типов ещё до запуска программы.2. В чём разница между объявлением и инициализацией переменной?
Ответ
Объявление — это создание переменной определённого типа без присвоения значения (`int x;`). Инициализация — присвоение первого значения переменной (`x = 5;`). Можно объединить в одну строку: `int x = 5;`.3. Что выведет этот код?
int x;
System.out.println(x);
Ответ
Программа не скомпилируется — ошибка "variable x might not have been initialized". Локальные переменные не имеют значения по умолчанию.4. Какой суффикс нужен для литерала типа long?
Ответ
`L` (заглавная предпочтительнее строчной `l`, чтобы не путать с единицей `1`). Пример: `long x = 5000000000L;`5. Что выведет код?
double result = 0.1 + 0.2;
System.out.println(result);
Ответ
`0.30000000000000004` — из-за особенностей представления дробных чисел в двоичной системе (IEEE 754), а не ровно `0.3`.6. Сколько байт занимает тип int?
Ответ
4 байта (32 бита), диапазон примерно от -2.1 до +2.1 миллиарда.7. Что произойдёт при выполнении этого кода?
byte b = 127;
b = (byte)(b + 1);
System.out.println(b);
Ответ
Выведет `-128` — переполнение (overflow): при выходе за верхнюю границу диапазона `byte` значение "перескакивает" на нижнюю границу.8. Какой тип данных используется по умолчанию для дробных чисел, если не указан суффикс?
Ответ
`double`. Поэтому `float price = 19.99;` без суффикса `f` вызовет ошибку компиляции (несовместимость типов).9. Верно ли, что boolean isReady = 1; — корректный код в Java?
Ответ
Неверно. В Java `boolean` НЕ совместим с числами — нельзя присвоить `0`/`1` вместо `true`/`false`. Это вызовет ошибку компиляции.10. Что такое final в контексте переменной?
Ответ
Модификатор, делающий переменную константой — значение можно присвоить один раз, повторное присвоение вызовет ошибку компиляции.11. Как по конвенции называются константы в Java?
Ответ
ЗАГЛАВНЫМИ_БУКВАМИ с подчёркиванием между словами, например `MAX_USERS`, `PI_VALUE`.12. Что выведет код?
char letter = 'A';
System.out.println((int) letter);
Ответ
`65` — числовой Unicode/ASCII-код символа `'A'`. `char` внутренне представлен как число.13. Какой стиль именования переменных принят в Java (camelCase, snake_case или PascalCase)?
Ответ
camelCase — первое слово с маленькой буквы, последующие слова с заглавной: `studentAge`, `totalPrice`.14. Почему в Java существует 4 разных целочисленных типа (byte, short, int, long), а не один универсальный?
Ответ
Для оптимизации использования памяти — выбор типа под конкретный диапазон значений экономит память, особенно критично при работе с большими массивами данных.15. Что произойдёт при компиляции этого кода?
int x = 10, y = 20;
final int MAX = 100;
MAX = 200;
Ответ
Ошибка компиляции на строке `MAX = 200;` — "cannot assign a value to final variable MAX", т.к. `MAX` объявлена как константа (`final`) и уже была инициализирована значением `100`.🔄 ДОМАШНЕЕ ЗАДАНИЕ
Задача 1: "Паспорт товара"
Напиши программу Product.java, моделирующую характеристики товара в интернет-магазине:
- Название товара (пока пропусти или используй char для первой буквы — String будет в след. уроке)
- Цена (
double) - Количество на складе (
int) - В наличии ли товар (
boolean) - Рейтинг товара от 1 до 5 (
byte, т.к. диапазон маленький) - Скидка в процентах, объявленная как
finalконстанта
Выведи все характеристики в консоль в читаемом формате, а также рассчитай итоговую цену со скидкой.
Пример вывода:
=== Информация о товаре ===
Цена: 1500.0
Количество на складе: 42
В наличии: true
Рейтинг: 5
Скидка: 10.0%
Цена со скидкой: 1350.0
Обязательные требования:
- Минимум 5 переменных разных типов
- Использование хотя бы одной
final-константы - Комментарии, объясняющие расчёт скидки
Задача 2: "Демонстрация всех подводных камней"
Напиши ОДНУ программу PitfallsDemo.java, которая последовательно (с комментариями-пояснениями перед каждым блоком) демонстрирует:
- Переполнение
byteпри увеличении сверх максимума - Ошибку неточности
doubleпри сложении0.1 + 0.2 - Разницу между
float(с суффиксомf) иdoubleдля одного и того же числа123.456789— сравни, сколько значащих цифр сохраняется у каждого - Приведение
charк числу и обратно
Критерии оценки: все 4 пункта продемонстрированы с понятным выводом в консоль, каждый блок кода предваряется комментарием, объясняющим, что демонстрируется.
Задача 3: "Мини-калькулятор возраста в разных единицах" (комплексная, объединяет с Уроком 1)
Напиши программу, которая:
- Объявляет переменную
int ageInYears = 25; - Вычисляет и выводит: возраст в месяцах (
int), возраст в днях (приблизительно,long, т.к. число может быть большим), возраст в часах (long) - Использует константу
final int DAYS_IN_YEAR = 365; - Форматирует вывод так, чтобы каждая единица измерения была на отдельной строке с использованием
println
Пример вывода:
Возраст в годах: 25
Возраст в месяцах: 300
Возраст в днях: 9125
Возраст в часах: 219000
Критерии оценки: корректные расчёты, использование минимум типов int и long, использование final-константы, применение техник вывода из Урока 1.
📚 ДОПОЛНИТЕЛЬНЫЕ МАТЕРИАЛЫ
Официальная документация:
- Oracle: Primitive Data Types — официальное описание всех примитивов
- Oracle: Variables — про правила именования и объявления
На что обратить особое внимание:
- Разница между
float/doubleи необходимость суффиксов — частый вопрос на собеседованиях - Проблема неточности вычислений с плавающей точкой — классический вопрос "почему
0.1 + 0.2 != 0.3" задают почти на каждом джуниор-собеседовании - Переполнение целочисленных типов — важно для понимания багов в реальных проектах (в частности, знаменитый "Y2K38 problem" связан именно с переполнением
int)
Частые ошибки новичков:
- Забывают суффикс
Lдля больших чисел (long) илиfдляfloat - Путают одинарные и двойные кавычки (
charvsString— про это подробно в следующем уроке) - Используют
doubleдля денежных расчётов там, где нужна точность (правильно —BigDecimal, разберём позже) - Пытаются сравнивать
booleanс числами0/1(что не работает в Java, в отличие от некоторых других языков) - Забывают, что при делении двух
intрезультат всегдаint— дробная часть отбрасывается (например,7 / 2даст3, а не3.5) — подробно разберём при изучении операторов в следующих уроках
✅ ЧЕК-ЛИСТ ГОТОВНОСТИ
После этого урока ты должен уметь без подсказок:
- Объяснить, что такое статическая типизация и почему Java её использует
- Перечислить все 8 примитивных типов и их примерные диапазоны/размеры
- Объяснить разницу между объявлением и инициализацией переменной
- Правильно использовать суффиксы
Lдляlongиfдляfloat - Объяснить, почему
0.1 + 0.2 != 0.3вdouble - Объяснить, что такое переполнение (overflow) и привести пример
- Создавать константы через
finalи объяснить их назначение - Следовать конвенции camelCase при именовании переменных
- Объяснить, почему
charможно использовать в арифметических операциях - Понимать, что происходит в стеке при создании примитивных переменных
Если что-то из списка вызывает сомнение — вернись к соответствующему разделу теории перед переходом к Уроку 3 (String и ссылочные типы)! 🚀