метод finalize () прерывает выполнение в середине? - PullRequest
3 голосов
/ 20 июня 2019

Вопрос

У меня есть URLClassLoader анонимный класс. В нем я переопределил метод finalize(), чтобы объект автоматически закрывался при сборке мусора:

protected void finalize() throws Throwable {
    close();
}

и я переопределил close() метод для вывода некоторой информации:

public void close() throws IOException {
    System.out.println("Closing...");
    super.close();
    System.out.println("Closed.");
}

Сразу после создания этого объекта я призываю System.gc() уничтожить его. Как и ожидалось, вызывается метод finalize(), а затем вызывается метод close(), но я вижу только то, что Closing... выводится на консоль.

Почему выполнение никогда не достигает моего второго оператора print?


Примечания

Первое, что я подозревал, было то, что super.close() генерировал исключение, и все, что готовит объект для сборки мусора, поглощало исключение, поэтому я попытался перехватить любой Throwable и распечатать его:

public void close() throws IOException {
    System.out.println("Closing...");
    try {
        super.close();
        System.out.println("Closed.");
    } catch (Throwable e) {
        e.printStackTrace();
    }
}

Но я получил точно такой же вывод, как и раньше: Closing.... Следующее, что я сделал, это проверил, что произойдет, если я закрою загрузчик классов вручную, поэтому я просто вызвал .close() на моем загрузчике классов, сразу после его создания, вместо запуска System.gc (); В этом случае оба моих оператора печати были выполнены:

Closing...
Closed.
...