Основные типы данных в Java

В этом уроке разберём примитивные и ссылочные типы данных Java, диапазоны их значений, преобразование типов и классы-обёртки.

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

Все типы в Java делятся на две большие группы: примитивные (хранят само значение) и ссылочные (хранят ссылку на объект в памяти).

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

Примитивных типов ровно восемь. Четыре целочисленных, два с плавающей точкой, символьный и логический.

Тип

Размер

Диапазон

Пример

byte

8 бит

−128 … 127

byte b = 100;

short

16 бит

−32 768 … 32 767

short s = 10000;

int

32 бита

≈ ±2,1 млрд

int i = 100000;

long

64 бита

≈ ±9,2·10¹⁸

long l = 100000L;

float

32 бита

~7 значащих цифр

float f = 234.5f;

double

64 бита

~15 значащих цифр

double d = 123.4;

char

16 бит

один символ Unicode

char c = 'A';

boolean

1 бит

true или false

boolean ok = true;

Обратите внимание на суффиксы: целочисленный литерал по умолчанию имеет тип int, поэтому большое число для long помечают суффиксом L, а дробный литерал по умолчанию — double, поэтому для float ставят суффикс f.

public class Main {
    public static void main(String[] args) {
        int year = 2024;
        long population = 8_000_000_000L;   // подчёркивания делают число читаемым
        double pi = 3.14159;
        float price = 19.99f;
        char grade = 'A';
        boolean isJavaFun = true;

        System.out.println(year);
        System.out.println(population);
        System.out.println(pi);
        System.out.println(grade);
        System.out.println(isJavaFun);
    }
}

Вывод:

2024
8000000000
3.14159
A
true

Переполнение

У целочисленных типов фиксированный диапазон. Если выйти за его границы, значение «заворачивается» по кругу — это называют переполнением. Никакой ошибки не возникает, поэтому тип нужно выбирать с запасом.

byte b = 127;   // максимум для byte
b++;            // выходим за границу
System.out.println(b);   // не 128, а −128

Вывод:

-128

Преобразование типов

Из «меньшего» типа в «больший» Java преобразует значения автоматически — это расширяющее преобразование. Обратно, из большего в меньший, нужно приводить вручную (сужающее преобразование), и часть данных при этом может потеряться.

int i = 100;
double d = i;          // int → double автоматически
System.out.println(d); // 100.0

double price = 99.99;
int rounded = (int) price;   // double → int — явное приведение, дробь отбрасывается
System.out.println(rounded); // 99

Вывод:

100.0
99

Ссылочные типы

Всё, что не является одним из восьми примитивов, — ссылочный тип: строки String, массивы, классы из библиотеки и ваши собственные классы. Переменная такого типа хранит не само значение, а ссылку на объект в куче (heap).

String name = "Анна";          // объект String
int[] scores = {90, 85, 100};     // массив — тоже объект

System.out.println(name);
System.out.println(scores.length); // у объекта есть поля и методы
System.out.println(scores[2]);

Вывод:

Анна
3
100

Ссылочная переменная может не указывать ни на какой объект — тогда её значение равно null. Попытка обратиться к методу null-ссылки приведёт к NullPointerException.

Классы-обёртки

Иногда примитив нужно представить как объект — например, чтобы положить в коллекцию. Для каждого примитива есть класс-обёртка: intInteger, doubleDouble, charCharacter и так далее. Java умеет автоматически упаковывать и распаковывать значения (autoboxing).

Integer boxed = 42;          // автоупаковка int → Integer
int back = boxed;            // автораспаковка Integer → int

System.out.println(Integer.MAX_VALUE);          // полезные константы
System.out.println(Integer.parseInt("256"));    // разбор строки в число

Вывод:

2147483647
256

Ключевое слово var

Начиная с Java 10 для локальных переменных можно не писать тип явно — компилятор выведет его сам по значению. Это сокращает запись, но переменная всё равно остаётся строго типизированной.

var message = "Привет";   // выведен тип String
var count = 10;            // выведен тип int
var prices = new double[]{1.5, 2.0};

System.out.println(message.toUpperCase());
System.out.println(count * 2);

Вывод:

ПРИВЕТ
20

Коротко

  • В Java 8 примитивных типов и неограниченное число ссылочных.
  • Примитив хранит значение, ссылочная переменная — ссылку на объект (или null).
  • Расширяющее преобразование происходит само, сужающее требует явного приведения.
  • Классы-обёртки превращают примитив в объект; var выводит тип автоматически.
Проверьте себя
1. Сколько примитивных типов данных в Java?
A6
B8
C10
DНеограниченно
2. Каким суффиксом помечают литерал типа long?
Af
BL
Cd
Di
3. Что произойдёт при выполнении: byte b = 127; b++;?
Ab станет 128
Bb станет −128 из-за переполнения
CОшибка компиляции
DПрограмма упадёт с исключением
4. Какое преобразование требует явного приведения типа?
Aint → double
Bbyte → int
Cdouble → int
Dfloat → double