Класс в Java — это описание (чертеж), по которому создаются объекты: он задает, какие у будущего объекта будут поля (данные) и методы (поведение). Объект — это конкретный экземпляр класса, созданный по этому чертежу и живущий в памяти. Одно объявление класса — и сколько угодно объектов по нему. Ниже разберем, чем класс отличается от объекта, что такое поля и методы, зачем нужен конструктор, ключевое слово new, this и ссылки. Все примеры запускаются на Java 25 LTS.
Содержание
Класс и объект: чертеж против конкретной вещи
Держите в голове аналогию-якорь: класс — это чертеж дома, а объект — конкретный дом, построенный по этому чертежу. Чертеж один, домов по нему можно построить много, и каждый дом стоит на своем участке и красится в свой цвет. В коде это выглядит так: описываете класс Cat один раз, а объектов-котов создаете сколько нужно, и у каждого своя кличка и свой возраст.
Путаница «класс или объект» — самая частая у новичка, поэтому развожу термины сразу и явно.
| Признак | Класс (class) | Объект (object) |
|---|---|---|
| Что это | описание, чертеж | конкретный экземпляр |
| Сколько бывает | один на тип | сколько угодно |
| Память под данные | само объявление не выделяет память под поля экземпляра | под свои поля выделяется при создании |
| Как появляется | пишется в коде через class |
создается через new |
| Пример | Cat |
barsik, murka |
Уточнение к строке про память: класс как таковой загружается в память в виде метаданных, это упрощение относится именно к полям экземпляра. Память под них резервируется в момент создания объекта, а не в момент объявления класса.
Минимальный рабочий пример целиком
Сначала — законченный класс, который компилируется и печатает результат. Разбор по строкам идет ниже.
public class Cat {
String name; // поле: кличка
int age; // поле: возраст
void meow() { // метод: поведение
System.out.println(name + " говорит: мяу");
}
public static void main(String[] args) {
Cat cat = new Cat(); // создаем объект по чертежу Cat
cat.name = "Барсик"; // задаем поля объекта
cat.age = 3;
cat.meow(); // вызываем метод объекта
System.out.println(cat.name + ", возраст " + cat.age);
}
}
Вывод в консоли:
Барсик говорит: мяу
Барсик, возраст 3
Что здесь произошло по шагам:
class Cat { ... }— объявление класса. Пока это только чертеж, ни одного кота еще нет.String name;иint age;— поля (переменные экземпляра). Это состояние будущего объекта.void meow()— метод. Это поведение объекта, именованный блок кода, который можно вызывать много раз.new Cat()— создание объекта. Именно здесь под кота выделяется память, и переменнаяcatполучает ссылку на него.cat.name,cat.meow()— обращение к полям и методам конкретного объекта через точку.
Поля и методы: данные и поведение
Поле — это переменная, объявленная внутри класса и хранящая часть состояния объекта. У кота это кличка и возраст. Метод — это действие, которое объект умеет выполнять: у кота это meow().
Метод может принимать аргументы и возвращать значение. Тип возвращаемого значения пишется перед именем метода, а void означает, что метод ничего не возвращает.
int max(int a, int b) { // принимает два числа, возвращает большее
if (a > b) {
return a;
}
return b;
}
Если вызвать max(7, 4), метод вернет 7. Обратите внимание: у метода max в скобках объявлены параметры a и b, а конкретные 7 и 4 при вызове — это аргументы.
Конструктор и ключевое слово this
Задавать поля по одному после создания (cat.name = ...) неудобно и легко забыть. Для этого есть конструктор — специальный метод, который вызывается при new и заполняет объект начальными данными. Имя конструктора совпадает с именем класса, а тип возвращаемого значения у него не указывается вовсе.
public class Cat {
String name;
int age;
Cat(String name, int age) { // конструктор
this.name = name; // this.name - поле объекта
this.age = age; // name - параметр конструктора
}
void meow() {
System.out.println(name + " говорит: мяу");
}
public static void main(String[] args) {
Cat barsik = new Cat("Барсик", 3);
Cat murka = new Cat("Мурка", 5);
barsik.meow();
System.out.println(murka.name + ", возраст " + murka.age);
}
}
Вывод:
Барсик говорит: мяу
Мурка, возраст 5
Здесь важен this. Параметр конструктора называется name, и поле объекта тоже называется name. Внутри конструктора простое name — это параметр, а this.name — поле текущего объекта. this — это ссылка на тот объект, для которого сейчас работает метод или конструктор. Строка this.name = name читается как «положить значение параметра в поле объекта». Если убрать this, поле не заполнится: присваивание name = name просто перезапишет параметр сам в себя.
Обратите внимание и на другое: barsik и murka — два разных объекта одного класса. У каждого своя копия полей, изменение одного не трогает другой.
Ключевое слово new и ссылки
Переменная типа класса хранит не сам объект, а ссылку на него — адрес объекта в памяти. Поэтому две переменные могут указывать на один и тот же объект. Это ключевой момент, на котором новички ошибаются.
Cat a = new Cat("Барсик", 3);
Cat b = a; // b получает ту же ссылку, новый объект НЕ создается
b.age = 10; // меняем возраст через b
System.out.println(a.age); // печатает 10
Вывод:
10
Хотя мы меняли b.age, изменилось и a.age, потому что a и b — это две ссылки на один объект. new вызывался один раз, значит объект в памяти один. Сравните с ситуацией, где new вызван дважды:
Cat a = new Cat("Барсик", 3);
Cat b = new Cat("Барсик", 3); // второй объект, отдельный
b.age = 10;
System.out.println(a.age); // печатает 3
Вывод:
3
Здесь два независимых объекта, и изменение одного не влияет на другой, даже если кличка совпадает. Равенство == для таких переменных сравнивает именно ссылки (один это объект или разные), а не содержимое полей.
Частая ошибка: обращение к объекту, которого нет
Локальная переменная-ссылка не указывает ни на какой объект, пока вы не присвоили ей результат new. Попытка вызвать метод у неинициализированной локальной переменной не скомпилируется.
Неверно:
Cat cat; // объявили ссылку, но объект не создали
cat.meow(); // обращаемся к несуществующему объекту
Результат компиляции (javac):
error: variable cat might not have been initialized
cat.meow();
^
Исправление — создать объект через new до обращения к нему:
Cat cat = new Cat("Барсик", 3);
cat.meow(); // теперь объект есть, метод вызывается
Отдельно стоит знать про поля: поле-ссылка, которое вы не инициализировали, по умолчанию равно null (пустая ссылка). Обращение к нему компилируется, но падает уже при выполнении с NullPointerException. Поэтому и здесь правило простое: сначала new, потом обращение.
Выводы
- Класс — это чертеж (описание полей и методов), объект — конкретный экземпляр по этому чертежу; одного класса хватает на сколько угодно объектов.
- Поля хранят состояние объекта, методы задают его поведение; обращение к ним идет через точку у конкретного объекта.
- Конструктор заполняет объект начальными данными при
new, аthisвнутри него отличает поле объекта от одноименного параметра. - Переменная класса хранит ссылку на объект, а не сам объект:
Cat b = aне создает новый объект, оба имени указывают на один экземпляр. - Объект появляется только после
new; обращение к неинициализированной ссылке дает ошибку компиляции (локальная переменная) илиNullPointerException(поле со значениемnull).
Где применяется / связь с практикой
Классы и объекты — это фундамент любого кода на Java: от простого консольного приложения до серверов и Android-приложений вы описываете сущности классами и работаете с их объектами. Понимание связки «класс — чертеж, объект — экземпляр, new — создание, this — текущий объект, ссылка — адрес» снимает большую часть ошибок новичка еще до знакомства с наследованием и интерфейсами.
Освойте тему на практике
Разобрать это на практике с проверкой кода наставником помогает курс Java Basic: там классы, объекты и ООП идут от простых примеров к рабочему проекту. Посмотреть формат занятий и задать вопрос преподавателю можно на открытых уроках Otus — они бесплатные и проходят регулярно.
FAQ
Можно ли создать объект без конструктора?
Да. Если вы не написали ни одного конструктора, компилятор добавляет конструктор по умолчанию без параметров, и new Cat() работает. Как только вы объявите свой конструктор с параметрами, конструктор по умолчанию исчезает, и вызывать нужно именно ваш.
В чем разница между полем и локальной переменной?
Поле объявляется внутри класса и живет столько же, сколько объект; у каждого объекта своя копия поля. Локальная переменная объявляется внутри метода, существует только во время его работы и не привязана к конкретному объекту.
Обязательно ли имя класса должно совпадать с именем файла?
Для публичного класса (public class Cat) — да: файл должен называться Cat.java. Это требование Java к публичным классам верхнего уровня, иначе компилятор выдаст ошибку.



