Карта / Синтаксис и типы / Примитивные типы

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

Примитивные типы — 8 базовых типов Java. Они хранят простое значение напрямую (не объекты) — это фундамент, на котором стоит всё остальное.

На старте реально нужны пять: int, long, double, boolean, char. Остальные — редко.

Целые числа
intобычные числа25
longочень большие9000000000L
shortнебольшие (редко)1000
byteкрошечные (редко)−100
Дробные числа
doubleдробные (по умолчанию)3.14
floatдробные (реже)3.14f
Символ
charодин символ'A'
Логический
booleanда / нетtrue
⚠️ String — не примитив, это объект (текст). Поэтому пишется с большой буквы.

Главное на старте

  • целые — int, очень большие — long;
  • дробные — double;
  • символ — char (в одинарных кавычках: 'A'), текст — String (в двойных: "Артур");
  • да/нет — boolean.
Копнуть глубже

Сколько памяти занимает каждый тип:

типвесчто вмещает
byte1 байт−128…127
short2 байта±32 тыс
int4 байта±2 млрд
long8 байт±9 квинтиллионов
float4 байтадробные, ~7 цифр
double8 байтдробные, ~15 цифр
char2 байтаодин символ
boolean~1 байтtrue / false

Зачем разные типы, почему не сделать один? Это баланс «память ↔ диапазон»:

  • Память. Миллион чисел в long (8 байт) — это 8 МБ, в int — 4 МБ, в byte — 1 МБ. На больших объёмах разница огромная.
  • Диапазон. int не вместит 9 миллиардов (id, время в мс) — нужен long. А для возраста хватит и byte.
  • Точность. double точнее, чем float.
  • Скорость. Меньше памяти → больше данных влезает в кэш процессора → быстрее.

Один тип был бы либо прожорливым (всё long), либо тесным (всё byte). Разные типы — выбираешь под задачу. Для очень больших чисел не забывай суффиксы: long x = 9000000000L;, float f = 3.14f;.

Под капотом

Где живёт примитив, зависит от того, где он объявлен:

  • Локальная переменная (в методе) → на стеке → самый быстрый доступ.
  • Поле объекта (в классе) → внутри объекта в куче → доступ через ссылку на объект, чуть медленнее.
  • static-поле → в области класса (Metaspace), одно на все объекты.

Что делает компилятор:

  • Поля получают значение по умолчанию автоматически (int → 0, boolean → false). Локальные переменные — нет: не задал значение — ошибка компиляции.
  • static final примитив = константа времени компиляции. Компилятор подставляет значение прямо в код (inline) — в рантайме обращения к полю вообще нет, это быстрее всего. static final int MAX = 100; → везде вместо MAX стоит 100.
  • Поля инициализируются сверху вниз в порядке объявления, до тела конструктора.

Ещё: char на самом деле — число (код символа в Unicode). 'A' равно 65, и его можно складывать: 'A' + 1 даст 66 ('B').

🎤 Закрыл тему, если можешь объяснить:
• какие 8 примитивов и чем String от них отличается;
• зачем нужны разные типы и сколько весит каждый (если дошёл до 2-го слоя);
• чем доступ к локальному примитиву отличается от поля класса (если дошёл до 3-го слоя).