¡ESTO DEBE SER OBSOLETO CON JAVA 9!
¡Úselo en su java.util.Cleaner
lugar! (O sun.misc.Cleaner
en JRE más antiguo)
Publicación original:
Descubrí que el uso de PhantomReferences tiene casi la misma cantidad de trampas que los métodos de finalizador (pero menos problemas una vez que lo haces bien). He escrito una pequeña solución (un marco muy pequeño para usar PhantomReferences) para Java 8. Permite usar expresiones lambda como devoluciones de llamada que se ejecutarán después de que se haya eliminado el objeto. Puede registrar las devoluciones de llamada para recursos internos que deben cerrarse. Con esto he encontrado una solución que me funciona ya que la hace mucho más práctica.
https://github.com/claudemartin/java-cleanup
Aquí hay un pequeño ejemplo para mostrar cómo se registra una devolución de llamada:
class Foo implements Cleanup {
public Foo() {
this.registerCleanup((value) -> {
try {
value.close();
} catch (Exception e) {
logger.warning("closing resource failed", e);
}
}, this.resource);
}
Y luego está el método aún más simple para el cierre automático, haciendo aproximadamente lo mismo que el anterior:
this.registerAutoClose(this.resource);
Para responder tu pregunta:
[entonces para qué sirve]
No puedes limpiar algo que no existe. Pero podría haber tenido recursos que aún existen y deben limpiarse para poder eliminarlos.
Pero, ¿de qué sirve este concepto / clase?
No es necesariamente para hacer nada con ningún efecto que no sea depurar / registrar. O quizás por estadísticas. Lo veo más como un servicio de notificación del GC. También podría querer usarlo para eliminar datos agregados que se vuelven irrelevantes una vez que se elimina el objeto (pero probablemente haya mejores soluciones para eso). Los ejemplos a menudo mencionan que las conexiones de la base de datos deben cerrarse, pero no veo cómo esto es una buena idea ya que no podría trabajar con transacciones. Un marco de aplicación proporcionará una solución mucho mejor para eso.
¿Alguna vez ha usado esto en alguno de sus proyectos, o tiene algún ejemplo en el que deberíamos usar esto? ¿O este concepto está hecho solo para el punto de vista de la entrevista;)
Lo uso principalmente solo para registrar. Entonces puedo rastrear los elementos eliminados y ver cómo funciona GC y cómo se puede modificar. No ejecutaría ningún código crítico de esta manera. Si es necesario cerrar algo, debe hacerlo en una declaración try-with-resource-statement. Y lo uso en pruebas unitarias, para asegurarme de que no tengo pérdidas de memoria. De la misma manera que lo hace jontejj. Pero mi solución es un poco más general.