ЦЕ ПОВИННО ЗАСТАВИТИСЯ З JAVA 9!
Використовуйте java.util.Cleaner
замість цього! (Або sun.misc.Cleaner
на старіших JRE)
Оригінальний допис:
Я виявив, що використання PhantomReferences має майже таку ж кількість підводних каменів, як і методи фіналізатора (але менше проблем, як тільки ви все зрозумієте). Я написав невелике рішення (дуже маленький фреймворк для використання PhantomReferences) для Java 8. Це дозволяє використовувати лямбда-вирази як зворотні виклики для запуску після видалення об’єкта. Ви можете зареєструвати зворотні виклики для внутрішніх ресурсів, які слід закрити. Завдяки цьому я знайшов рішення, яке підходить мені, оскільки робить його набагато практичнішим.
https://github.com/claudemartin/java-cleanup
Ось невеликий приклад, який показує, як реєструється зворотний дзвінок:
class Foo implements Cleanup {
public Foo() {
this.registerCleanup((value) -> {
try {
value.close();
} catch (Exception e) {
logger.warning("closing resource failed", e);
}
}, this.resource);
}
А ще є ще простіший спосіб автоматичного закриття, який робить приблизно те саме, що і вище:
this.registerAutoClose(this.resource);
Щоб відповісти на ваші запитання:
[тоді яка користь від цього]
Не можна прибирати те, чого не існує. Але він міг мати ресурси, які все ще існують і потребують очищення, щоб їх можна було видалити.
Але яка користь від цього поняття / класу?
Не обов’язково робити що-небудь з будь-яким ефектом, окрім налагодження / реєстрації. А може, для статистики. Я бачу це більше як служба сповіщень від GC. Ви також можете використовувати його для видалення агрегованих даних, які стають неактуальними після видалення об’єкта (але, мабуть, для цього існують кращі рішення). У прикладах часто згадується підключення до бази даних, яке слід закрити, але я не розумію, наскільки це така гарна ідея, оскільки ви не могли працювати з транзакціями. Фреймворк додатків забезпечить набагато краще рішення для цього.
Ви коли-небудь використовували це у будь-якому з своїх проектів, або у вас є якийсь приклад, де ми повинні використовувати це? Або ця концепція створена лише для точки зору співбесіди;)
Я використовую його здебільшого лише для реєстрації. Тож я можу простежити вилучені елементи і подивитися, як працює GC, і їх можна налаштувати. Я б не запускав жоден критичний код таким чином. Якщо щось потрібно закрити, то це слід зробити у заяві try-with-resource-statement. І я використовую його в модульних тестах, щоб переконатися, що у мене немає витоків пам'яті. Так само, як це робить jontejj. Але моє рішення трохи загальніше.