Если вы уже писали код на другом языке, Java покажется одновременно знакомой и непривычно строгой. Здесь у каждой переменной заранее объявлен тип, программа не запустится, пока не скомпилируется, а часть привычных вольностей просто запрещена. Разберём базу: как объявить переменную, чем int отличается от Integer, почему строки нельзя изменить и из чего состоит управляющая логика.
Зачем такая строгость
Java — язык со статической типизацией. Это значит, что тип каждой переменной известен ещё до запуска программы, на этапе компиляции. Компилятор проверяет, что вы не складываете число со списком и не вызываете у строки несуществующий метод. Ошибки такого рода ловятся сразу, а не во время работы у пользователя.
Короткая формула: в Java сначала компиляция, потом запуск. Исходный код (.java) превращается в байт-код (.class), который исполняет виртуальная машина JVM. Поэтому опечатка в имени метода — это не падение на проде, а ошибка сборки прямо в редакторе.
Точка входа: метод main
Любая Java-программа начинается с метода main. JVM ищет именно его и запускает первым:
public class App {
public static void main(String[] args) {
System.out.println("Привет, Java"); // вывод строки в консоль
}
}
Разберём сигнатуру по словам:
public— метод доступен извне, JVM должна его увидеть;static— метод принадлежит классу, а не объекту, его можно вызвать без создания экземпляра;void— метод ничего не возвращает;String[] args— массив аргументов командной строки.
Пока достаточно запомнить эту строку как «волшебное заклинание старта». Что такое class, public и static на самом деле — подробно в статье про ООП.
Переменные и var
Переменная объявляется по схеме «тип имя = значение»:
int age = 30;
String name = "Анна";
boolean active = true;
Тип слева обязателен — компилятор должен знать, что вы собираетесь хранить. Но с Java 10 появилось ключевое слово var: оно просит компилятор вывести тип автоматически из правой части.
var age = 30; // компилятор видит число → int
var name = "Анна"; // видит строку → String
var items = new ArrayList<String>(); // тип ясен из конструктора
Важно: var — это не «нетипизированная» переменная, как в динамических языках. Тип всё равно фиксируется намертво, просто его не нужно писать руками. Записать потом в age строку нельзя. И var работает только там, где тип очевиден из значения, — для локальных переменных внутри методов.
Примитивы против объектов
В Java есть два мира значений.
Примитивные типы — это «голые» значения, лежащие в памяти напрямую. Их восемь, но на старте важны эти:
int count = 100; // целое, 32 бита
long big = 9_000_000L; // большое целое, 64 бита (подчёркивания для читаемости)
double price = 19.99; // дробное
boolean ok = false; // true / false
char letter = 'A'; // один символ в одинарных кавычках
Объектные (ссылочные) типы — это всё остальное: строки, списки, ваши собственные классы. Переменная хранит не само значение, а ссылку на объект в памяти. У каждого примитива есть объектный «двойник»-обёртка: int → Integer, long → Long, boolean → Boolean, double → Double.
Зачем нужны обёртки? Многие части стандартной библиотеки (например, коллекции) умеют работать только с объектами, а не с примитивами. В список нельзя положить int, но можно Integer.
Автобоксинг
Чтобы не переключаться между мирами вручную, Java делает преобразование сама — это автобоксинг (примитив → обёртка) и анбоксинг (обёртка → примитив):
Integer boxed = 5; // автобоксинг: int 5 → Integer
int back = boxed; // анбоксинг: Integer → int
Удобно, но есть две ловушки. Первая: обёртка может быть null, и попытка распаковать null в примитив уронит программу с NullPointerException. Вторая: обёртки нужно сравнивать через .equals(), а не через == — про это в статье об исключениях и в материале про коллекции. Правило простое: если значение точно есть и оно одно — берите примитив int; если значение может отсутствовать или его надо положить в коллекцию — берите Integer.
Строки и их неизменяемость
String — это объект, и в Java строки неизменяемы (immutable). Любая операция, которая «меняет» строку, на самом деле создаёт новую, а старая остаётся прежней:
String greeting = "Привет";
String full = greeting + ", мир"; // создалась НОВАЯ строка
// greeting по-прежнему "Привет"
Это сделано ради безопасности и предсказуемости: раз строку нельзя испортить, её можно спокойно передавать куда угодно и использовать как ключ. Минус — если в цикле склеивать тысячи строк через +, каждый раз создаётся новый объект. Для такого случая есть StringBuilder:
var sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
sb.append(i).append(' '); // меняем один и тот же буфер
}
String result = sb.toString(); // "0 1 2 3 4 "
Ещё две полезные мелочи. Сравнивать строки по содержимому нужно через .equals(), а не == (последнее сравнивает ссылки). А с Java 15 для многострочного текста есть «текстовые блоки» в тройных кавычках:
String json = """
{
"name": "Анна"
}
""";
Операторы
Операторы в Java привычны почти любому программисту:
int sum = 2 + 3; // арифметика: + - * / %
boolean adult = age >= 18; // сравнение: == != < > <= >=
boolean both = active && adult; // логика: && (и), || (или), ! (не)
Логические && и || «ленивы»: если левая часть && уже false, правую Java даже не вычисляет. Это удобно для проверок вида if (user != null && user.isActive()) — второе условие не выполнится, если user равен null.
Есть и тернарный оператор — короткая форма выбора одного из двух значений:
String label = adult ? "взрослый" : "несовершеннолетний";
Управляющие конструкции
Ветвление — if / else if / else:
if (price > 100) {
System.out.println("дорого");
} else if (price > 50) {
System.out.println("средне");
} else {
System.out.println("дёшево");
}
Циклы — for, while и for-each для перебора коллекций:
for (int i = 0; i < 3; i++) { // классический счётчик
System.out.println(i);
}
int n = 3;
while (n > 0) { // пока условие истинно
n--;
}
var names = List.of("Анна", "Борис");
for (String person : names) { // for-each: по каждому элементу
System.out.println(person);
}
Выбор по значению — switch. В современной Java есть короткая стрелочная форма, которая может сразу возвращать результат и не требует break:
String role = "admin";
int level = switch (role) {
case "admin" -> 3;
case "editor" -> 2;
default -> 1; // обязательная ветка «всё остальное»
};
Старая форма с case ... : и break тоже работает, но стрелочный switch короче и не даёт случайно «провалиться» в следующую ветку.
Коротко
- Java — статически типизированный язык: тип известен на этапе компиляции, ошибки ловятся до запуска.
- Любая программа стартует с метода
public static void main(String[] args). varне отменяет типизацию — он лишь выводит тип автоматически для локальных переменных.- Примитивы (
int,double,boolean) хранят значение напрямую; объектные обёртки (Integer,Double) могут бытьnullи нужны для коллекций. Перевод между ними — автобоксинг. - Строки неизменяемы: «изменение» создаёт новый объект; для активной склейки используйте
StringBuilder, для сравнения —.equals(). - Управляющие конструкции стандартны:
if/else,for,while,for-eachи современный стрелочныйswitch.
Что почитать дальше
- ООП в Java: классы, объекты, наследование — что на самом деле стоит за
class,publicиstatic. - Коллекции Java — где обёртки
Integerи неизменяемость строк проявляются на практике. - Инструменты Java-разработчика — как собрать и запустить код, который мы здесь писали.