Переменные и типы данных
Переменная
Переменная связывает имя, статический тип и значение в некоторой области видимости.
int retryCount = 3;
String status = "READY";Имя пишут в lowerCamelCase, константу — обычно в UPPER_SNAKE_CASE. Идентификатор не начинается с цифры и не может совпадать с ключевым словом. Главное правило — имя должно выражать роль, а не только тип: retryCount полезнее, чем number.
Примитивные типы
| Тип | Размер | Диапазон/смысл |
|---|---|---|
byte | 8 бит | целое -128..127 |
short | 16 бит | целое -32768..32767 |
int | 32 бита | знаковое целое |
long | 64 бита | знаковое целое |
float | 32 бита | IEEE 754, ограниченная точность |
double | 64 бита | IEEE 754, основной тип дробных вычислений |
char | 16 бит | кодовая единица UTF-16, не всегда целый Unicode-символ |
boolean | JVM не задаёт размер переменной | true или false |
Литерал целого по умолчанию имеет тип int, дробного — double:
long timeout = 10_000L;
float ratio = 0.75F;
int mask = 0b1010;
int color = 0xFF00AA;Ссылочные типы
Ссылочная переменная хранит ссылку на объект либо null:
String first = new String("ok");
String second = first;Здесь две переменные указывают на один объект. Присваивание ссылки не копирует объект. Конкретное представление ссылки в памяти не является частью языка Java.
Массивы, классы, интерфейсы, enum и record — ссылочные типы. Их поведение при передаче в метод связано с тем, что Java всегда передаёт аргументы по значению: для объекта копируется значение ссылки.
Инициализация и область видимости
Поля получают значения по умолчанию (0, false, null), локальные переменные компилятор требует явно инициализировать перед чтением.
class Counter {
private int total; // 0
int next(boolean increment) {
int delta;
if (increment) {
delta = 1;
} else {
delta = 0;
}
return total += delta;
}
}Область видимости ограничена блоком { ... }. Чем уже область и короче жизнь переменной, тем проще проверить её состояние.
final и var
final запрещает повторно присвоить переменную, но не делает объект неизменяемым:
final List<String> names = new ArrayList<>();
names.add("Ada"); // допустимо
// names = new ArrayList<>(); // недопустимоvar просит компилятор вывести статический тип локальной переменной. Это не динамическая типизация:
var names = new ArrayList<String>(); // тип ArrayList<String>var нельзя использовать для полей, параметров и возвращаемых типов. Он полезен, когда тип очевиден из правой части и имя сохраняет смысл.
char и Unicode
Один char — кодовая единица UTF-16. Символ за пределами Basic Multilingual Plane занимает пару char, поэтому String.length() считает кодовые единицы, а не пользовательские символы. Для Unicode-кода применяют методы codePoint....
Ловушки
- Считать ссылку самим объектом или ожидать копию при присваивании.
- Забывать суффиксы
LиF. - Считать
final Listнеизменяемым списком. - Использовать
float/doubleдля точных денежных сумм. - Считать, что любой Unicode-символ помещается в один
char. - Давать
varимя вродеdata, скрывающее назначение значения.
Вопросы на собеседовании
- Чем примитивный тип отличается от ссылочного?
- Какие значения по умолчанию получают поля и локальные переменные?
- Делает ли
finalобъект неизменяемым? - Почему
charне всегда равен одному символу? - Является ли
varдинамической типизацией? - Что именно передаётся в метод при передаче объекта?
Связанные заметки
Классы обертки Java · Преобразование типов Java · Работа с числовыми данными · Работа со строковыми данными · Объекты Java · Immutable классы и данные