Again, organized as a JUnit class of tests.
Some methods and parameters have been renamed for greater clarity
package chapter6;
import org.junit.jupiter.api.Test;
import java.io.FileWriter;
import java.io.IOException;
// ---
// "resources/fpij/FileWriterARM.java" on p. 109
// ARM "Automatic Resource Management" (AutoCloseable + Try with Resources)
// ---
class FileWriterARM implements AutoCloseable {
private final FileWriter writer;
public FileWriterARM(final String fileName) throws IOException {
writer = new FileWriter(fileName);
}
public void writeStuff(final String message) throws IOException {
writer.write(message);
}
// this shall be called from a try-with-resources
public void close() throws IOException {
System.out.println("close called automatically...");
writer.close();
}
}
// ---
// EAM "Execute Around Method Pattern", basically the "Inversion of Control"
// pattern - "don't call us, we will call you!"
// "resources/fpij/FileWriterEAM.java" on p.111
// ---
class FileWriterEAM {
private final FileWriter writer;
// private constructor
private FileWriterEAM(final String fileName) throws IOException {
writer = new FileWriter(fileName);
}
// private close()
private void close() throws IOException {
System.out.println("close called automatically...");
writer.close();
}
public void writeStuff(final String message) throws IOException {
writer.write(message);
}
// "resources/fpij/FileWriterEAM.java" on p.111, bottom
// Rather than "block", which is confusing, let's call the action part "injectedAction"
// and the interface likewise.
public static void use(final String fileName, final InjectedAction<FileWriterEAM, IOException> injectedAction) throws IOException {
final FileWriterEAM writerEAM = new FileWriterEAM(fileName);
try {
injectedAction.accept(writerEAM);
} finally {
writerEAM.close();
}
}
}
// ---
// The code "resources/fpij/FileWriterExample.java" on p.106, verbatim.
// https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/io/FileWriter.html
// ---
class FileWriterExample {
private final FileWriter writer;
public FileWriterExample(final String fileName) throws IOException {
writer = new FileWriter(fileName);
}
public void writeStuff(final String message) throws IOException {
writer.write(message);
}
// "resources/fpij/FileWriterExample.java" on p.108
public void finalize() throws IOException { //Deprecated in Java 9
writer.close();
}
@Deprecated
public void close() throws IOException {
writer.close();
}
}
// ---
// "resources/fpij/UseInstance.java" on p.112
// Originally called "UseInstance", "InjectedAction" sounds better to me.
// Note the interesting use of a generic Throwable.
// ---
@FunctionalInterface
interface InjectedAction<T, X extends Throwable> {
void accept(T instance) throws X;
}
// =================================
public class WorkingWithResources_Cleanup {
// We don't want the file to appear in the IDE filespace, so "/tmp" seems like
// a good target directory. The $$ will be replaced.
private final static String tt = "/tmp/foofile-$$.txt";
// "resources/fpij/FileWriterExample.java" on p.107
@Test
void fileWriterExample() throws IOException {
String targetFile = tt.replace("$$","test1");
final FileWriterExample writerExample = new FileWriterExample(targetFile);
writerExample.writeStuff("peek-a-boo");
}
// "resources/fpij/FileWriterExample.java" on p.108
// DON'T IT LIKE THIS
@Test
void fileWriterExample_badAsCloseMayNotBeCalled() throws IOException {
String targetFile = tt.replace("$$","test2");
final FileWriterExample writerExample = new FileWriterExample(targetFile);
writerExample.writeStuff("peek-a-boo");
writerExample.close();
}
// "resources/fpij/FileWriterExample.java" on p.108
@Test
void fileWriterExample_betterWithFinally() throws IOException {
String targetFile = tt.replace("$$","test3");
final FileWriterExample writerExample = new FileWriterExample(targetFile);
try {
writerExample.writeStuff("peek-a-boo");
}
finally {
writerExample.close();
}
}
// "resources/fpij/FileWriterARM.java" on p.109
// ARM "Automatic Resource Management" (AutoCloseable + Try with Resources)
@Test
void fileWriterExampleARM() throws IOException {
String targetFile = tt.replace("$$","test4");
try (final FileWriterARM writerARM = new FileWriterARM(targetFile)) {
writerARM.writeStuff("peek-a-boo");
System.out.println("done with the resource...");
}
}
// "resources/fpij/FileWriterEAM.java" on p.112
// EAM "Execute Around Method Pattern" (pass an "injected action").
// Note that FileWriterEAM.use has just a static use().
@Test
void fileWriterExampleEAM() throws IOException {
String targetFile = tt.replace("$$","test5");
FileWriterEAM.use(targetFile, writerEAM -> writerEAM.writeStuff("sweet"));
}
// "resources/fpij/FileWriterEAM.java" on p. 113
@Test
void fileWriterExampleEAM2() throws IOException {
String targetFile = tt.replace("$$","test6");
FileWriterEAM.use(targetFile, writerEAM -> {
writerEAM.writeStuff("how");
writerEAM.writeStuff("sweet");
});
}
}