import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.Cleaner;
public final class HasResource implements AutoCloseable {
// This has a Thread backing it so you want to share your cleaner across the whole lib
private static final Cleaner CLEANER = Cleaner.create();
private final FileOutputStream outputStream;
private final Cleaner.Cleanable cleanable;
// You don't want your cleaner task to be a lambda so you don't accidentally capture a
// ref. to the wrapping object.
private static final class CleanerTask implements Runnable {
private final FileOutputStream outputStream;
private CleanerTask(FileOutputStream outputStream) {
this.outputStream = outputStream;
}
@Override
public void run() {
try {
this.outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public HasResource() {
try {
this.outputStream = new FileOutputStream("ex.csv");
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
this.cleanable = CLEANER.register(this, new CleanerTask(this.outputStream));
}
@Override
public void close() {
// This has "at most once" semantics so if they close it the cleaner won't run your cleanup logic a second time
this.cleanable.clean();
}
}