Есть ли способ создать регистр обработчика, который будет вызываться именно тогда, когда будет выпущена последняя ссылка на определенный объект?
Примером может служить объект, который поддерживается физическим файлом данных, и как только на объект перестают ссылаться, файл следует закрыть, а затем переименовать. Было бы хорошо, если бы это было возможно без явного вызова метода «close» для этого объекта.
Все механизмы уведомления, о которых я знаю из справочной области Weak / Phantom, говорят только о том, что уведомление произойдет в какой-то момент времени, но нет гарантии, когда это произойдет ...




Короче нет.
Спецификация Java явно запрещает вам знать, когда была выпущена последняя ссылка. Реализации JVM (и оптимизации) зависят от этого. Крюка нет.
Насколько я понимаю, и я некоторое время искал "деструктор" для объектов Java, нет никакого способа узнать, когда вы потеряете последнюю ссылку. Java отслеживает ссылки на объекты, но из соображений производительности обновляет эту информацию только во время сборки мусора.
Ближе всего к этому методу finalize, который следует вызывать во время сборки мусора, но нет гарантии, что он будет вызван даже тогда.
Проблема в том, «Как это реализовать, если что-то не содержит ссылки на объект?»
Даже если вы могли бы решить эту проблему, скажем, с помощью службы, которую мы вызовем HandleManager, HandleManager затем должен был бы создать новую ссылку на объект для передачи вашему обработчику. Затем ваш обработчик мог либо (а) сохранить ссылку на него, что сбило бы с толку HandleManager, который ожидал уничтожить объект, на который нет ссылки; или (b) освободить ссылку, что означает, что последняя ссылка была снова освобождена, что означает, что Обработчик должен быть вызван снова ....
Этого нельзя сделать с Java - насколько я могу судить, ему нужен сборщик мусора, подсчитывающий ссылки. Рассматривали ли вы возможность открытия и закрытия файла физических данных вашего объекта по мере необходимости, вместо того, чтобы держать его открытым в течение всего времени существования объекта?
То, что вы описываете, является возможным обходным путем. Было бы неплохо, если бы был способ реализовать такие чистки таким образом, чтобы они вызывались, когда это необходимо. Однако это требует, чтобы клиенты объекта не забывали о явной очистке. Возможный источник ошибки.
Если вам нужно управлять внешними ресурсами, такими как файлы, лучшее, что вы можете сделать в java, - это функция close () (какое бы имя вы ни выбрали). Вы можете использовать finalize () в качестве страхового полиса «пояс и подтяжки», но это непредсказуемо по времени. Таким образом, вашей основной линией защиты должна быть функция close ().
Смотрите мой ответ Зачем вообще реализовывать finalize ()?
Я думаю, WeakReference делает то, что вы хотите. WeakReference помещается в ReferenceQueue, как только становится недостижимым (т.е. все сильные ссылки исчезают).
См. Эту статью Итан Николас.
Если вас беспокоит, что некоторые ссылки не достигают ReferenceQueue при завершении работы, сохраните список всех созданных объектов (используя WeakReferences или PhantomReferences). Добавьте ловушку выключения, которая проверяет список на наличие невыполненных ссылок и выполняет любое действие, которое вам нужно.
Не могли бы вы сослаться на спецификацию?