← Назад к вопросам

Что происходит при вызове оператора new

1.3 Junior🔥 221 комментариев
#JVM и управление памятью#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Процесс создания объекта при вызове оператора new

Оператор new — один из самых важных операторов в Java. Это не просто команда выделить память — это целая последовательность операций, которые выполняются в определённом порядке. Понимание этого процесса критично для работы с объектами, конструкторами и инициализацией.

1. Пошаговый процесс при вызове new

Когда выполняется строка User user = new User("John", 30); происходит следующее:

Шаг 1: Загрузка класса

Если класс ещё не загружен в память, JVM загружает его:

public class User {
    private static int totalUsers = 0; // инициализируется один раз
    
    static {
        System.out.println("Статический блок - один раз при загрузке класса");
    }
    
    private String name;
    private int age;
}

Шаг 2: Выделение памяти в heap

JVM выделяет нужное количество памяти для объекта с учётом всех полей.

Шаг 3: Инициализация полей default значениями

Все поля инициализируются нулями: null для объектов, 0 для чисел, false для boolean.

Шаг 4: Выполнение инициализаторов полей

public class Example {
    private String description = "Default";
    private long createdAt = System.currentTimeMillis();
}

Шаг 5: Выполнение инициализирующих блоков

public class User {
    private String name;
    
    {
        System.out.println("Инициализирующий блок - перед конструктором");
        name = "Unknown";
    }
    
    public User(String n) {
        System.out.println("Конструктор");
        name = n;
    }
}

Шаг 6: Вызов конструктора

Выполняется код конструктора, передаются параметры.

Шаг 7: Возврат ссылки на объект

new возвращает ссылку на созданный объект.

2. Полный порядок инициализации при наследовании

public class Animal {
    private static String staticField = "static";
    
    static {
        System.out.println("1. Static block Animal (один раз)");
    }
    
    private String name = "defaultName";
    
    {
        System.out.println("2. Instance initializer Animal");
    }
    
    public Animal(String name) {
        System.out.println("3. Constructor Animal");
        this.name = name;
    }
}

public class Dog extends Animal {
    private String breed = "defaultBreed";
    
    {
        System.out.println("4. Instance initializer Dog");
    }
    
    public Dog(String name, String breed) {
        super(name);
        System.out.println("5. Constructor Dog");
        this.breed = breed;
    }
}

// При new Dog("Rex", "Labrador"):
// 1. Static block Animal (один раз)
// 2. Instance initializer Animal
// 3. Constructor Animal
// 4. Instance initializer Dog
// 5. Constructor Dog

3. Цепочка конструкторов (Constructor Chaining)

public class User {
    private String name;
    private int age;
    
    public User() {
        this("Unknown", 0); // Вызовет другой конструктор
    }
    
    public User(String name) {
        this(name, 0); // Вызовет конструктор с двумя параметрами
    }
    
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// new User("John") → User(String) → User(String, int)

4. Что происходит при ошибке в конструкторе

public class Problematic {
    private String name;
    
    public Problematic(String name) throws IllegalArgumentException {
        if (name == null) {
            throw new IllegalArgumentException("Name cannot be null");
        }
        this.name = name;
    }
}

// При исключении в конструкторе:
try {
    Problematic p = new Problematic(null);
    // Код сюда не попадёт - переменная не инициализируется
} catch (IllegalArgumentException e) {
    System.out.println("Ошибка: " + e.getMessage());
}

5. Время жизни объекта

User user = new User("John", 30);
// Объект создан и находится в памяти (heap)

user = null;
// Ссылка обнулена, объект может быть удалён GC

new User("Jane", 25);
// Объект создан, но нет ссылки на него
// Сразу становится кандидатом на удаление GC

6. Порядок выполнения операций

Первый раз при загрузке класса (один раз):

  1. Загрузить класс
  2. Инициализировать статические поля
  3. Выполнить статические блоки

При каждом создании объекта (new):

  1. Выделить память
  2. Инициализировать поля default значениями
  3. Выполнить инициализаторы полей
  4. Выполнить инициализирующие блоки
  5. Вызвать конструктор
  6. Вернуть ссылку

Для наследования: сначала родитель → потом потомок

7. Ленивая инициализация

public class LazyInit {
    private List<String> items; // null по умолчанию
    
    public List<String> getItems() {
        if (items == null) {
            items = new ArrayList<>(); // Инициализируется при первом использовании
        }
        return items;
    }
}

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

Что происходит при вызове оператора new | PrepBro