Вопрос
У меня есть 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.