В документации к пакету содержится вводящая в заблуждение фраза: «Объект фантомно достижим , если он не является ни сильно, ни мягко, ни слабо достижимым, он завершен, и некоторые ссылки на фантомотносится к нему ».
То, что« некоторая фантомная ссылка »не подчеркивает тот факт, что сам эталонный объект должен быть достижимым, что указано в разделе Уведомление :
Связь между зарегистрированным ссылочным объектом и его очередью является односторонней.То есть очередь не отслеживает ссылки, которые зарегистрированы в ней.Если зарегистрированная ссылка сама по себе становится недоступной, то она никогда не будет помещена в очередь.
Поскольку фантомная достижимость не имеет практических последствий, за исключением того, что она потенциально может вызвать встраивание фантомных ссылок, этоэто все, что имеет значение.
Обратите внимание, что определения мягкой и слабой достижимости лучше:
- Объект является мягко достижимым , если он недостижимо, но может быть достигнуто путем обхода мягкой ссылки.
- Объект является слабо достижимым , если он не является ни сильно, ни мягко достижимым, но может быть достигнут путем обхода слабой ссылки.…
Здесь подчеркивается, что объект должен быть доступен через эталонные объекты, что означает, что эталонные объекты должны быть также достижимы.
Проблема с определениемФантомная достижимость аналогичным образом заключается в том, что фантомно достижимые объекты на самом деле недостижимы, так как PhantomReference
переопределяет метод get()
, чтобы всегда возвращать null
, поэтому приложение не может достичь референта и, следовательно, не пройти через любой фантомдостижимые объекты.
Возможно, лучшим определением было бы
- Объект фантомно достижим , если он не является ни сильным, ни мягким, ни слабымдостижимо, оно было завершено, но может быть достигнуто сборщиком мусора путем обхода фантомной ссылки.
С этим определением было бы довольно ясно, что вашпример с собственной ссылкой не будет работать, как если бы он не работал с WeakReference
или SoftReference
.Обратите внимание, что когда в вашем классе нет выделенного finalize()
метода, нет практической разницы между использованием WeakReference
или PhantomReference
.
. Кажется, что даже разработчики API не полностью понимали последствия,поскольку спецификация до Java 9 содержала правило:
В отличие от мягких и слабых ссылок, фантомные ссылки не очищаются сборщиком мусора автоматически, поскольку они ставятся в очередь.Объект, достижимый с помощью фантомных ссылок, будет оставаться таким до тех пор, пока все такие ссылки не будут очищены или сами не станут недоступными.
, что явно игнорирует точку, в которой объект фантомно достижимый не являетсядостижимо, по крайней мере, с точки зрения приложения, и сохранение его фантомно достижимым с точки зрения сборщика мусора не имеет практической пользы.Не заставлять объект жить снова, это самая разница для завершения.Но обратите внимание, что в этом месте в документации признается, что если сама фантомная ссылка становится недоступной, референт перестает быть фантомно достижимым .
Начиная с Java 9, фантомные ссылки автоматически очищаются при постановке в очередьТаким образом, единственное практическое следствие перехода объекта из фантомно достижимого в недостижимого - это ссылка на фантом в ссылке.Что требует доступности эталонного объекта.